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 {
|
pub fn statistics(&self) -> BundleStatistics {
|
||||||
let bundles = self.list_bundles();
|
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 {
|
BundleStatistics {
|
||||||
|
hash_methods, compressions,
|
||||||
raw_size: ValueStats::from_iter(|| bundles.iter().map(|b| b.raw_size as f32)),
|
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)),
|
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 prelude::*;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::collections::HashMap;
|
||||||
use serde;
|
use serde;
|
||||||
use rand;
|
use rand;
|
||||||
|
|
||||||
|
@ -137,7 +138,15 @@ impl Default for BundleInfo {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BundleStatistics {
|
pub struct BundleStatistics {
|
||||||
raw_size: ValueStats,
|
pub raw_size: ValueStats,
|
||||||
encoded_size: ValueStats,
|
pub encoded_size: ValueStats,
|
||||||
chunk_count: 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>,
|
backup_name: Option<String>,
|
||||||
inode: Option<String>
|
inode: Option<String>
|
||||||
},
|
},
|
||||||
|
Stats {
|
||||||
|
repo_path: PathBuf
|
||||||
|
},
|
||||||
Copy {
|
Copy {
|
||||||
repo_path_src: PathBuf,
|
repo_path_src: PathBuf,
|
||||||
backup_name_src: String,
|
backup_name_src: String,
|
||||||
|
@ -464,6 +467,11 @@ pub fn parse() -> Result<(log::Level, Arguments), ErrorCode> {
|
||||||
.arg(Arg::from_usage("<REPO>")
|
.arg(Arg::from_usage("<REPO>")
|
||||||
.help(tr!("Path of the repository"))
|
.help(tr!("Path of the repository"))
|
||||||
.validator(|val| validate_repo_path(val, true, Some(false), Some(false)))))
|
.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")
|
.subcommand(SubCommand::with_name("bundleinfo")
|
||||||
.about(tr!("Display information on a bundle"))
|
.about(tr!("Display information on a bundle"))
|
||||||
.arg(Arg::from_usage("<REPO>")
|
.arg(Arg::from_usage("<REPO>")
|
||||||
|
@ -739,6 +747,15 @@ pub fn parse() -> Result<(log::Level, Arguments), ErrorCode> {
|
||||||
inode: inode.map(|v| v.to_string())
|
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)) => {
|
("copy", Some(args)) => {
|
||||||
let (repository_src, backup_src, _inode) =
|
let (repository_src, backup_src, _inode) =
|
||||||
parse_repo_path(args.value_of("SRC").unwrap(), true, Some(true), Some(false))
|
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) {
|
fn print_bundle(bundle: &StoredBundle) {
|
||||||
tr_println!("Bundle {}", bundle.info.id);
|
tr_println!("Bundle {}", bundle.info.id);
|
||||||
tr_println!(" - Mode: {:?}", bundle.info.mode);
|
tr_println!(" - Mode: {:?}", bundle.info.mode);
|
||||||
|
@ -859,10 +914,15 @@ pub fn run() -> Result<(), ErrorCode> {
|
||||||
print_backup(&backup);
|
print_backup(&backup);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
println!("{:?}", repo.statistics());
|
|
||||||
print_repoinfo(&repo.info());
|
print_repoinfo(&repo.info());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Arguments::Stats {
|
||||||
|
repo_path
|
||||||
|
} => {
|
||||||
|
let mut repo = try!(open_repository(&repo_path, false));
|
||||||
|
print_repostats(&repo.statistics());
|
||||||
|
}
|
||||||
Arguments::Mount {
|
Arguments::Mount {
|
||||||
repo_path,
|
repo_path,
|
||||||
backup_name,
|
backup_name,
|
||||||
|
|
|
@ -34,7 +34,7 @@ quick_error!{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Copy, Eq, PartialEq)]
|
#[derive(Clone, Debug, Copy, Eq, PartialEq, Hash)]
|
||||||
pub enum CompressionMethod {
|
pub enum CompressionMethod {
|
||||||
Deflate, // Standardized
|
Deflate, // Standardized
|
||||||
Brotli, // Good speed and ratio
|
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 {
|
pub struct Compression {
|
||||||
method: CompressionMethod,
|
method: CompressionMethod,
|
||||||
level: u8
|
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 {
|
pub enum HashMethod {
|
||||||
Blake2,
|
Blake2,
|
||||||
Murmur3
|
Murmur3
|
||||||
|
|
Loading…
Reference in New Issue