diff --git a/bin/core/imag-diagnostics/Cargo.toml b/bin/core/imag-diagnostics/Cargo.toml index 10fa5f80..0cff95b2 100644 --- a/bin/core/imag-diagnostics/Cargo.toml +++ b/bin/core/imag-diagnostics/Cargo.toml @@ -16,6 +16,8 @@ homepage = "http://imag-pim.org" [dependencies] clap = ">=2.17" version = "2.0.1" +toml = "0.4" +toml-query = "0.4" libimagstore = { version = "0.5.0", path = "../../../lib/core/libimagstore" } libimagrt = { version = "0.5.0", path = "../../../lib/core/libimagrt" } diff --git a/bin/core/imag-diagnostics/src/main.rs b/bin/core/imag-diagnostics/src/main.rs index 2e9a1c30..e71e7fe3 100644 --- a/bin/core/imag-diagnostics/src/main.rs +++ b/bin/core/imag-diagnostics/src/main.rs @@ -33,6 +33,8 @@ )] extern crate clap; +extern crate toml; +extern crate toml_query; #[macro_use] extern crate version; extern crate libimagrt; @@ -41,21 +43,104 @@ extern crate libimagstore; use libimagrt::setup::generate_runtime_setup; use libimagerror::trace::MapErrTrace; +use libimagstore::store::FileLockEntry; +use libimagstore::iter::get::*; +use libimagstore::error::StoreError as Error; + +use toml::Value; +use toml_query::read::TomlValueReadExt; + +use std::collections::BTreeMap; mod ui; +struct Diagnostic { + pub entry_store_version: String, + pub header_sections: usize, + pub bytecount_content: usize, + pub overall_byte_size: usize, + pub verified: bool, +} + +impl<'a> From> for Diagnostic { + + fn from(entry: FileLockEntry<'a>) -> Diagnostic { + Diagnostic { + entry_store_version: entry + .get_header() + .read("imag.version") + .map(|opt| match opt { + Some(&Value::String(ref s)) => s.clone(), + Some(_) => "Non-String type in 'imag.version'".to_owned(), + None => "No version".to_owned(), + }) + .unwrap_or("Error reading version".to_owned()), + header_sections: match entry.get_header() { + &Value::Table(ref map) => map.keys().count(), + _ => 0 + }, + bytecount_content: entry.get_content().as_str().len(), + overall_byte_size: entry.to_str().as_str().len(), + verified: entry.verify().is_ok(), + } + } +} + fn main() { let rt = generate_runtime_setup("imag-diagnostics", &version!()[..], "Print diagnostics about imag and the imag store", ui::build_ui); - let n = rt.store() + let diags = rt.store() .entries() .map_err_trace_exit(1) .unwrap() - .count(); + .into_get_iter(rt.store()) + .map(|e| { + e.map_err_trace_exit_unwrap(1) + .ok_or(Error::from("Unable to get entry".to_owned())) + .map_err_trace_exit_unwrap(1) + }) + .map(Diagnostic::from) + .collect::>(); + let mut version_counts : BTreeMap = BTreeMap::new(); + let mut sum_header_sections = 0; + let mut sum_bytecount_content = 0; + let mut sum_overall_byte_size = 0; + let mut verified_count = 0; + let mut unverified_count = 0; + + for diag in diags.iter() { + sum_header_sections += diag.header_sections; + sum_bytecount_content += diag.bytecount_content; + sum_overall_byte_size += diag.overall_byte_size; + + let n = version_counts.get(&diag.entry_store_version).map(Clone::clone).unwrap_or(0); + version_counts.insert(diag.entry_store_version.clone(), n+1); + + if diag.verified { + verified_count += 1; + } else { + unverified_count += 1; + } + } + + let n = diags.len(); + + println!("imag version {}", version!()); + println!(""); println!("{} entries", n); + for (k, v) in version_counts { + println!("{} entries with store version '{}'", v, k); + } + if n != 0 { + println!("{} header sections in the average entry", sum_header_sections / n); + println!("{} average content bytecount", sum_bytecount_content / n); + println!("{} average overall bytecount", sum_overall_byte_size / n); + println!("{} verified entries", verified_count); + println!("{} unverified entries", unverified_count); + } }