mirror of https://github.com/dswd/zvault
more stats
This commit is contained in:
parent
d47edee08f
commit
56c916f585
|
@ -525,10 +525,25 @@ impl BundleDb {
|
|||
|
||||
pub fn statistics(&self) -> BundleStatistics {
|
||||
let bundles = self.list_bundles();
|
||||
let bundles_meta: Vec<_> = bundles.iter().filter(|b| b.mode == BundleMode::Meta).collect();
|
||||
let bundles_data: Vec<_> = bundles.iter().filter(|b| b.mode == BundleMode::Data).collect();
|
||||
let mut hash_methods = HashMap::new();
|
||||
let mut compressions = HashMap::new();
|
||||
for bundle in &bundles {
|
||||
*hash_methods.entry(bundle.hash_method).or_insert(0) += 1;
|
||||
*compressions.entry(bundle.compression.clone()).or_insert(0) += 1;
|
||||
}
|
||||
BundleStatistics {
|
||||
hash_methods, compressions,
|
||||
raw_size: ValueStats::from_iter(|| bundles.iter().map(|b| b.raw_size as f32)),
|
||||
encoded_size: ValueStats::from_iter(|| bundles.iter().map(|b| b.encoded_size as f32)),
|
||||
chunk_count: ValueStats::from_iter(|| bundles.iter().map(|b| b.chunk_count as f32))
|
||||
chunk_count: ValueStats::from_iter(|| bundles.iter().map(|b| b.chunk_count as f32)),
|
||||
raw_size_meta: ValueStats::from_iter(|| bundles_meta.iter().map(|b| b.raw_size as f32)),
|
||||
encoded_size_meta: ValueStats::from_iter(|| bundles_meta.iter().map(|b| b.encoded_size as f32)),
|
||||
chunk_count_meta: ValueStats::from_iter(|| bundles_meta.iter().map(|b| b.chunk_count as f32)),
|
||||
raw_size_data: ValueStats::from_iter(|| bundles_data.iter().map(|b| b.raw_size as f32)),
|
||||
encoded_size_data: ValueStats::from_iter(|| bundles_data.iter().map(|b| b.encoded_size as f32)),
|
||||
chunk_count_data: ValueStats::from_iter(|| bundles_data.iter().map(|b| b.chunk_count as f32))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ pub use self::uploader::BundleUploader;
|
|||
use prelude::*;
|
||||
|
||||
use std::fmt;
|
||||
use std::collections::HashMap;
|
||||
use serde;
|
||||
use rand;
|
||||
|
||||
|
@ -137,7 +138,15 @@ impl Default for BundleInfo {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct BundleStatistics {
|
||||
raw_size: ValueStats,
|
||||
encoded_size: ValueStats,
|
||||
chunk_count: ValueStats
|
||||
pub raw_size: ValueStats,
|
||||
pub encoded_size: ValueStats,
|
||||
pub chunk_count: ValueStats,
|
||||
pub raw_size_meta: ValueStats,
|
||||
pub encoded_size_meta: ValueStats,
|
||||
pub chunk_count_meta: ValueStats,
|
||||
pub raw_size_data: ValueStats,
|
||||
pub encoded_size_data: ValueStats,
|
||||
pub chunk_count_data: ValueStats,
|
||||
pub hash_methods: HashMap<HashMethod, usize>,
|
||||
pub compressions: HashMap<Option<Compression>, usize>
|
||||
}
|
|
@ -75,6 +75,9 @@ pub enum Arguments {
|
|||
backup_name: Option<String>,
|
||||
inode: Option<String>
|
||||
},
|
||||
Stats {
|
||||
repo_path: PathBuf
|
||||
},
|
||||
Copy {
|
||||
repo_path_src: PathBuf,
|
||||
backup_name_src: String,
|
||||
|
@ -464,6 +467,11 @@ pub fn parse() -> Result<(log::Level, Arguments), ErrorCode> {
|
|||
.arg(Arg::from_usage("<REPO>")
|
||||
.help(tr!("Path of the repository"))
|
||||
.validator(|val| validate_repo_path(val, true, Some(false), Some(false)))))
|
||||
.subcommand(SubCommand::with_name("stats")
|
||||
.about(tr!("Display statistics on a repository"))
|
||||
.arg(Arg::from_usage("<REPO>")
|
||||
.help(tr!("Path of the repository"))
|
||||
.validator(|val| validate_repo_path(val, true, Some(false), Some(false)))))
|
||||
.subcommand(SubCommand::with_name("bundleinfo")
|
||||
.about(tr!("Display information on a bundle"))
|
||||
.arg(Arg::from_usage("<REPO>")
|
||||
|
@ -739,6 +747,15 @@ pub fn parse() -> Result<(log::Level, Arguments), ErrorCode> {
|
|||
inode: inode.map(|v| v.to_string())
|
||||
}
|
||||
}
|
||||
("stats", Some(args)) => {
|
||||
let (repository, _backup, _inode) = parse_repo_path(
|
||||
args.value_of("REPO").unwrap(),
|
||||
true,
|
||||
Some(false),
|
||||
Some(false)
|
||||
).unwrap();
|
||||
Arguments::Stats { repo_path: repository }
|
||||
}
|
||||
("copy", Some(args)) => {
|
||||
let (repository_src, backup_src, _inode) =
|
||||
parse_repo_path(args.value_of("SRC").unwrap(), true, Some(true), Some(false))
|
||||
|
|
|
@ -313,6 +313,61 @@ fn print_repoinfo(info: &RepositoryInfo) {
|
|||
);
|
||||
}
|
||||
|
||||
fn print_repostats(stats: &RepositoryStatistics) {
|
||||
tr_println!("Index\n=====");
|
||||
let index_usage = stats.index.count as f32 / stats.index.capacity as f32;
|
||||
tr_println!("Size: {}", to_file_size(stats.index.size as u64));
|
||||
tr_println!("Entries: {} / {}, {:.0}%", stats.index.count, stats.index.capacity, index_usage*100.0);
|
||||
let disp = &stats.index.displacement;
|
||||
tr_println!("Displacement:\n - average: {:.1}\n - stddev: {:.1}\n - over {:.1}: {:.0}, {:.1}%\n - maximum: {:.0}",
|
||||
disp.avg, disp.stddev, disp.avg + 2.0 * disp.stddev, disp.count_xl, disp.count_xl as f32 / disp.count as f32 * 100.0, disp.max);
|
||||
println!("");
|
||||
tr_println!("Bundles (all)\n=============");
|
||||
let rsize = &stats.bundles.raw_size;
|
||||
tr_println!("Raw size:\n - average: {}\n - stddev: {}\n - maximum: {}",
|
||||
to_file_size(rsize.avg as u64), to_file_size(rsize.stddev as u64), to_file_size(rsize.max as u64));
|
||||
let esize = &stats.bundles.encoded_size;
|
||||
tr_println!("Encoded size:\n - average: {}\n - stddev: {}\n - maximum: {}",
|
||||
to_file_size(esize.avg as u64), to_file_size(esize.stddev as u64), to_file_size(esize.max as u64));
|
||||
let ccount = &stats.bundles.chunk_count;
|
||||
tr_println!("Chunk count:\n - average: {:.1}\n - stddev: {:.1}\n - minimum: {:.0}\n - maximum: {:.0}", ccount.avg, ccount.stddev, ccount.min, ccount.max);
|
||||
println!("");
|
||||
tr_println!("Meta bundles\n============");
|
||||
let rsize = &stats.bundles.raw_size_meta;
|
||||
tr_println!("Raw size:\n - average: {}\n - stddev: {}\n - maximum: {}",
|
||||
to_file_size(rsize.avg as u64), to_file_size(rsize.stddev as u64), to_file_size(rsize.max as u64));
|
||||
let esize = &stats.bundles.encoded_size_meta;
|
||||
tr_println!("Encoded size:\n - average: {}\n - stddev: {}\n - maximum: {}",
|
||||
to_file_size(esize.avg as u64), to_file_size(esize.stddev as u64), to_file_size(esize.max as u64));
|
||||
let ccount = &stats.bundles.chunk_count_meta;
|
||||
tr_println!("Chunk count:\n - average: {:.1}\n - stddev: {:.1}\n - minimum: {:.0}\n - maximum: {:.0}", ccount.avg, ccount.stddev, ccount.min, ccount.max);
|
||||
println!("");
|
||||
tr_println!("Data bundles\n============");
|
||||
let rsize = &stats.bundles.raw_size_data;
|
||||
tr_println!("Raw size:\n - average: {}\n - stddev: {}\n - maximum: {}",
|
||||
to_file_size(rsize.avg as u64), to_file_size(rsize.stddev as u64), to_file_size(rsize.max as u64));
|
||||
let esize = &stats.bundles.encoded_size_data;
|
||||
tr_println!("Encoded size:\n - average: {}\n - stddev: {}\n - maximum: {}",
|
||||
to_file_size(esize.avg as u64), to_file_size(esize.stddev as u64), to_file_size(esize.max as u64));
|
||||
let ccount = &stats.bundles.chunk_count_data;
|
||||
tr_println!("Chunk count:\n - average: {:.1}\n - stddev: {:.1}\n - minimum: {:.0}\n - maximum: {:.0}", ccount.avg, ccount.stddev, ccount.min, ccount.max);
|
||||
println!("");
|
||||
tr_println!("Bundle methods\n==============");
|
||||
tr_println!("Compression:");
|
||||
for (compr, &count) in &stats.bundles.compressions {
|
||||
let compr_name = if let &Some(ref compr) = compr {
|
||||
compr.to_string()
|
||||
} else {
|
||||
tr!("none").to_string()
|
||||
};
|
||||
tr_println!(" - {}: {}, {:.1}%", compr_name, count, count as f32 / stats.bundles.raw_size.count as f32 * 100.0);
|
||||
}
|
||||
tr_println!("Hash:");
|
||||
for (hash, &count) in &stats.bundles.hash_methods {
|
||||
tr_println!(" - {}: {}, {:.1}%", hash.name(), count, count as f32 / stats.bundles.raw_size.count as f32 * 100.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn print_bundle(bundle: &StoredBundle) {
|
||||
tr_println!("Bundle {}", bundle.info.id);
|
||||
tr_println!(" - Mode: {:?}", bundle.info.mode);
|
||||
|
@ -859,10 +914,15 @@ pub fn run() -> Result<(), ErrorCode> {
|
|||
print_backup(&backup);
|
||||
}
|
||||
} else {
|
||||
println!("{:?}", repo.statistics());
|
||||
print_repoinfo(&repo.info());
|
||||
}
|
||||
}
|
||||
Arguments::Stats {
|
||||
repo_path
|
||||
} => {
|
||||
let mut repo = try!(open_repository(&repo_path, false));
|
||||
print_repostats(&repo.statistics());
|
||||
}
|
||||
Arguments::Mount {
|
||||
repo_path,
|
||||
backup_name,
|
||||
|
|
|
@ -34,7 +34,7 @@ quick_error!{
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Copy, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Copy, Eq, PartialEq, Hash)]
|
||||
pub enum CompressionMethod {
|
||||
Deflate, // Standardized
|
||||
Brotli, // Good speed and ratio
|
||||
|
@ -49,7 +49,7 @@ serde_impl!(CompressionMethod(u8) {
|
|||
});
|
||||
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub struct Compression {
|
||||
method: CompressionMethod,
|
||||
level: u8
|
||||
|
|
|
@ -105,7 +105,7 @@ impl<'a> Deserialize<'a> for Hash {
|
|||
}
|
||||
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
pub enum HashMethod {
|
||||
Blake2,
|
||||
Murmur3
|
||||
|
|
Loading…
Reference in New Issue