From 8a79b5866e54aa89148f64ca2c69ba5f787c46ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Veljko=20Rvovi=C4=87?= Date: Wed, 29 Jul 2026 10:05:02 +0000 Subject: [PATCH] Reformat with cargo fmt Mechanical only, no logic changes. Formatted with rustfmt 1.7.1-stable (Rust 1.81.0) at default settings. --- examples/acme.rs | 23 +- examples/growth.rs | 22 +- examples/histogram.rs | 28 +- examples/http_download.rs | 21 +- examples/http_server.rs | 51 ++- examples/iron_middleware.rs | 29 +- examples/physical.rs | 31 +- src/bin/mmvdump.rs | 3 +- src/client/metric/counter.rs | 32 +- src/client/metric/countvector.rs | 109 +++--- src/client/metric/gauge.rs | 32 +- src/client/metric/gaugevector.rs | 62 ++-- src/client/metric/histogram.rs | 136 ++++---- src/client/metric/mod.rs | 546 +++++++++++++++++-------------- src/client/metric/timer.rs | 42 ++- src/client/mod.rs | 149 ++++----- src/lib.rs | 15 +- src/mmv/mmvfmt.rs | 151 +++++---- src/mmv/mod.rs | 394 ++++++++++++++-------- src/private.rs | 4 +- tests/mmvfmt.rs | 8 +- 21 files changed, 1081 insertions(+), 807 deletions(-) diff --git a/examples/acme.rs b/examples/acme.rs index 82e4d26..7bf6cc1 100644 --- a/examples/acme.rs +++ b/examples/acme.rs @@ -1,21 +1,21 @@ -extern crate hornet; +extern crate hornet; extern crate rand; -use hornet::client::Client; use hornet::client::metric::*; +use hornet::client::Client; use rand::random; use std::thread; use std::time::Duration; fn main() { - let products = ["Anvils", "Rockets", "Giant_Rubber_Bands"]; let indom = Indom::new( &products, "Acme products", - "Most popular products produced by the Acme Corporation" - ).unwrap(); - + "Most popular products produced by the Acme Corporation", + ) + .unwrap(); + /* create three instance metrics */ let mut counts = InstanceMetric::new( @@ -52,8 +52,10 @@ fn main() { /* create a client, register the metrics with it, and export them */ - Client::new("acme").unwrap() - .export(&mut [&mut counts, &mut times, &mut queue_times]).unwrap(); + Client::new("acme") + .unwrap() + .export(&mut [&mut counts, &mut times, &mut queue_times]) + .unwrap(); /* update metrics */ @@ -74,7 +76,10 @@ fn main() { let queued_product = products[i]; let queue_time = *queue_times.val(queued_product).unwrap(); - queue_times.set_val(queued_product, queue_time + 1).unwrap().unwrap(); + queue_times + .set_val(queued_product, queue_time + 1) + .unwrap() + .unwrap(); } } } diff --git a/examples/growth.rs b/examples/growth.rs index ddcf0fb..8ccbf90 100644 --- a/examples/growth.rs +++ b/examples/growth.rs @@ -1,36 +1,34 @@ -extern crate hornet; +extern crate hornet; extern crate rand; -use hornet::client::Client; use hornet::client::metric::*; +use hornet::client::Client; use std::thread; use std::time::Duration; /* this examples demonstrates use of Counter and GaugeVector */ fn main() { + let mut n = Counter::new("n", 0, "Input to various functions", "").unwrap(); - let mut n = Counter::new( - "n", - 0, - "Input to various functions", "").unwrap(); - - let mut f_n = GaugeVector::new( + let mut f_n = GaugeVector::new( "functions", 0.0, &["log2(n)", "nlog2(n)", "n^2", "n^3", "n^4", "2^n", "10^n"], - "Growth of various functions", "").unwrap(); + "Growth of various functions", + "", + ) + .unwrap(); let client = Client::new("growth").unwrap(); client.export(&mut [&mut n, &mut f_n]).unwrap(); println!("Values mapped at {}", client.mmv_path().to_str().unwrap()); for _ in 0..60 { - let val = n.val() as f64; f_n.set("log2(n)", val.log2()).unwrap().unwrap(); - f_n.set("nlog2(n)", val*val.log2()).unwrap().unwrap(); + f_n.set("nlog2(n)", val * val.log2()).unwrap().unwrap(); f_n.set("n^2", val.powi(2)).unwrap().unwrap(); f_n.set("n^3", val.powi(3)).unwrap().unwrap(); f_n.set("n^4", val.powi(4)).unwrap().unwrap(); @@ -40,7 +38,5 @@ fn main() { n.up().unwrap(); thread::sleep(Duration::from_secs(1)); - } - } diff --git a/examples/histogram.rs b/examples/histogram.rs index a507b0f..61401b0 100644 --- a/examples/histogram.rs +++ b/examples/histogram.rs @@ -1,40 +1,44 @@ -extern crate hornet; +extern crate hornet; extern crate rand; -use hornet::client::Client; use hornet::client::metric::*; -use rand::thread_rng; +use hornet::client::Client; use rand::distributions::{IndependentSample, Range}; +use rand::thread_rng; /* For detailed usage and behaviour of the underlying HDR histogram object, - check out jonhoo's hdrsample crate at https://github.com/jonhoo/hdrsample + check out jonhoo's hdrsample crate at https://github.com/jonhoo/hdrsample */ fn main() { - /* pick parameters for the histogram */ let low = 1; let high = 100; let significant_figures = 5; - /* create a histogram metric */ + /* create a histogram metric */ - let mut hist = Histogram::new( + let mut hist = Histogram::new( "histogram", low, high, significant_figures, Unit::new().count(Count::One, 1).unwrap(), - "Simple histogram example", "" - ).unwrap(); + "Simple histogram example", + "", + ) + .unwrap(); /* export it to an mmv */ let client = Client::new("histogram").unwrap(); client.export(&mut [&mut hist]).unwrap(); - println!("Histogram mapped at {}", client.mmv_path().to_str().unwrap()); + println!( + "Histogram mapped at {}", + client.mmv_path().to_str().unwrap() + ); /* record 100 random values */ @@ -46,7 +50,7 @@ fn main() { } /* record a single random value 100 times */ - - hist.record_n(range.ind_sample(&mut thread_rng), 100).unwrap(); + hist.record_n(range.ind_sample(&mut thread_rng), 100) + .unwrap(); } diff --git a/examples/http_download.rs b/examples/http_download.rs index 9b84a34..e96fb16 100644 --- a/examples/http_download.rs +++ b/examples/http_download.rs @@ -1,9 +1,9 @@ -extern crate hornet; extern crate curl; +extern crate hornet; -use hornet::client::Client; -use hornet::client::metric::*; use curl::easy::Easy; +use hornet::client::metric::*; +use hornet::client::Client; /* this example uses the Timer metric to measure time spent @@ -13,18 +13,17 @@ use curl::easy::Easy; const URL: &'static str = "https://codeload.github.com/torvalds/linux/zip/master"; fn main() { - - let mut timer = Timer::new( - "time", - Time::Sec, - "Time elapsed downloading", "").unwrap(); + let mut timer = Timer::new("time", Time::Sec, "Time elapsed downloading", "").unwrap(); let mut bytes = Metric::new( "bytes", 0, Semantics::Discrete, Unit::new().space(Space::Byte, 1).unwrap(), - "Bytes downloaded so far", "").unwrap(); + "Bytes downloaded so far", + "", + ) + .unwrap(); let client = Client::new("download").unwrap(); client.export(&mut [&mut timer, &mut bytes]).unwrap(); @@ -38,11 +37,11 @@ fn main() { timer.start().ok(); bytes.set_val(bytes_downloaded as u64).unwrap(); true - }).unwrap(); + }) + .unwrap(); println!("Downloading from {}", URL); println!("Progress mapped at {}", client.mmv_path().to_str().unwrap()); easy.perform().unwrap(); - } diff --git a/examples/http_server.rs b/examples/http_server.rs index 2984fa9..5c4d5b5 100644 --- a/examples/http_server.rs +++ b/examples/http_server.rs @@ -1,14 +1,14 @@ -extern crate hornet; -extern crate hyper; extern crate futures; +extern crate hornet; +extern crate hyper; -use std::sync::{Mutex, Arc}; -use hornet::client::Client; -use hornet::client::metric::*; use futures::future::FutureResult; +use hornet::client::metric::*; +use hornet::client::Client; use hyper::header::{ContentLength, ContentType}; +use hyper::server::{Http, Request, Response, Service}; use hyper::{Get, StatusCode}; -use hyper::server::{Http, Service, Request, Response}; +use std::sync::{Arc, Mutex}; /* records count of HTTP GET requests on localhost:8000 @@ -20,7 +20,7 @@ use hyper::server::{Http, Service, Request, Response}; static URL: &'static str = "127.0.0.1:8000"; struct HTTPCounterService { - arc: Arc> + arc: Arc>, } impl Service for HTTPCounterService { @@ -32,7 +32,6 @@ impl Service for HTTPCounterService { fn call(&self, req: Request) -> Self::Future { futures::future::ok(match (req.method(), req.path()) { (&Get, "/") => { - let mut counter = self.arc.lock().unwrap(); /* increase the counter value by one */ @@ -43,54 +42,46 @@ impl Service for HTTPCounterService { .with_header(ContentLength(body.len() as u64)) .with_header(ContentType::plaintext()) .with_body(body) - - }, - _ => { - Response::new() - .with_status(StatusCode::NotFound) } + _ => Response::new().with_status(StatusCode::NotFound), }) } - } fn main() { + /* create a counter metric */ - /* create a counter metric */ - - let mut counter = Counter::new( + let mut counter = Counter::new( "get", - 0, // initial value - "GET request count", // short description - &format!("Count of GET requests on http://{}/", URL) // long description - ).unwrap(); + 0, // initial value + "GET request count", // short description + &format!("Count of GET requests on http://{}/", URL), // long description + ) + .unwrap(); /* export it to an mmv */ let client = Client::new("localhost.http").unwrap(); client.export(&mut [&mut counter]).unwrap(); - /* + /* since the counter could be updated concurrently, wrap it in a mutex. to have shared ownership of the mutex itself, wrap it in an atomic reference counting pointer */ - + let mutex = Mutex::new(counter); let arc = Arc::new(mutex); /* create and run the server */ let addr = URL.parse().unwrap(); - let server = Http::new().bind(&addr, move || { - Ok(HTTPCounterService { - arc: arc.clone() - }) - }).unwrap(); + let server = Http::new() + .bind(&addr, move || Ok(HTTPCounterService { arc: arc.clone() })) + .unwrap(); println!("Listening on http://{}", server.local_addr().unwrap()); println!("Counter mapped at {}", client.mmv_path().to_str().unwrap()); - server.run().unwrap(); - + server.run().unwrap(); } diff --git a/examples/iron_middleware.rs b/examples/iron_middleware.rs index 456747c..06e3c52 100644 --- a/examples/iron_middleware.rs +++ b/examples/iron_middleware.rs @@ -1,13 +1,13 @@ -extern crate iron; extern crate hornet; +extern crate iron; -use std::sync::Mutex; -use hornet::client::Client; use hornet::client::metric::*; -use iron::prelude::*; -use iron::middleware::BeforeMiddleware; +use hornet::client::Client; use iron::method::Method; +use iron::middleware::BeforeMiddleware; +use iron::prelude::*; use iron::status; +use std::sync::Mutex; /* this examples demonstrates usage of CountVector metric @@ -21,7 +21,7 @@ fn method_str(method: &Method) -> String { } struct MethodCounter { - pub metric: Mutex + pub metric: Mutex, } impl MethodCounter { @@ -37,12 +37,15 @@ impl MethodCounter { &method_str(&Method::Delete), &method_str(&Method::Head), &method_str(&Method::Trace), - &method_str(&Method::Connect) + &method_str(&Method::Connect), ], - "Counts of recieved HTTP request methods", "").unwrap(); - + "Counts of recieved HTTP request methods", + "", + ) + .unwrap(); + MethodCounter { - metric: Mutex::new(metric) + metric: Mutex::new(metric), } } } @@ -50,7 +53,7 @@ impl MethodCounter { impl BeforeMiddleware for MethodCounter { fn before(&self, req: &mut Request) -> IronResult<()> { match &req.method { - &Method::Extension(_) => {}, + &Method::Extension(_) => {} _ => { let mut counter = self.metric.lock().unwrap(); counter.up(&method_str(&req.method)).unwrap().unwrap(); @@ -73,9 +76,7 @@ fn main() { client.export(&mut [&mut *metric]).unwrap(); } - let mut chain = Chain::new(|_: &mut Request| { - Ok(Response::with((status::Ok, "Hello World!"))) - }); + let mut chain = Chain::new(|_: &mut Request| Ok(Response::with((status::Ok, "Hello World!")))); chain.link_before(method_counter); println!("Listening on http://{}", URL); diff --git a/examples/physical.rs b/examples/physical.rs index 7df280c..c28bc11 100644 --- a/examples/physical.rs +++ b/examples/physical.rs @@ -1,14 +1,13 @@ -extern crate hornet; +extern crate hornet; extern crate rand; -use hornet::client::Client; use hornet::client::metric::*; +use hornet::client::Client; use rand::{thread_rng, Rng}; use std::thread; use std::time::Duration; fn main() { - /* create three singleton metrics */ let mut color = Metric::new( @@ -18,17 +17,19 @@ fn main() { Unit::new(), "Color", "", - ).unwrap(); + ) + .unwrap(); let hz = Unit::new().time(Time::Sec, -1).unwrap(); let mut freq = Metric::new( - "frequency", // name (max 63 bytes) + "frequency", // name (max 63 bytes) thread_rng().gen::(), // initial value - Semantics::Instant, // semantics - hz, // unit - "", // optional short description (max 255 bytes) - "", // optional long description (max 255 bytes) - ).unwrap(); + Semantics::Instant, // semantics + hz, // unit + "", // optional short description (max 255 bytes) + "", // optional long description (max 255 bytes) + ) + .unwrap(); let mut photons = Metric::new( "photons", @@ -37,12 +38,15 @@ fn main() { Unit::new().count(Count::One, 1).unwrap(), "No. of photons", "Number of photons emitted by source", - ).unwrap(); + ) + .unwrap(); /* create a client, register the metrics with it, and export them */ - Client::new("physical_metrics").unwrap() - .export(&mut [&mut freq, &mut color, &mut photons]).unwrap(); + Client::new("physical_metrics") + .unwrap() + .export(&mut [&mut freq, &mut color, &mut photons]) + .unwrap(); /* update metric values */ @@ -54,5 +58,4 @@ fn main() { thread::sleep(Duration::from_secs(1)); } - } diff --git a/src/bin/mmvdump.rs b/src/bin/mmvdump.rs index a19ef5e..9d74cc0 100644 --- a/src/bin/mmvdump.rs +++ b/src/bin/mmvdump.rs @@ -5,8 +5,7 @@ use std::env; use std::path::Path; fn main() { - let path_arg = env::args().nth(1) - .expect("Specify path to mmv file"); + let path_arg = env::args().nth(1).expect("Specify path to mmv file"); let mmv_path = Path::new(&path_arg); print!("{}", mmv::dump(&mmv_path).unwrap()); diff --git a/src/client/metric/counter.rs b/src/client/metric/counter.rs index ad3eb47..ff70ec4 100644 --- a/src/client/metric/counter.rs +++ b/src/client/metric/counter.rs @@ -7,24 +7,29 @@ use super::*; /// `Count::One` scale, and `1` count dimension pub struct Counter { metric: Metric, - init_val: u64 + init_val: u64, } impl Counter { /// Creates a new counter metric with given initial value - pub fn new(name: &str, init_val: u64, shorthelp_text: &str, longhelp_text: &str) -> Result { + pub fn new( + name: &str, + init_val: u64, + shorthelp_text: &str, + longhelp_text: &str, + ) -> Result { let metric = Metric::new( name, init_val, Semantics::Counter, Unit::new().count(Count::One, 1)?, shorthelp_text, - longhelp_text + longhelp_text, )?; Ok(Counter { metric: metric, - init_val: init_val + init_val: init_val, }) } @@ -52,9 +57,14 @@ impl Counter { } impl MMVWriter for Counter { - private_impl!{} - - fn write(&mut self, ws: &mut MMVWriterState, c: &mut Cursor<&mut [u8]>, mmv_ver: Version) -> io::Result<()> { + private_impl! {} + + fn write( + &mut self, + ws: &mut MMVWriterState, + c: &mut Cursor<&mut [u8]>, + mmv_ver: Version, + ) -> io::Result<()> { self.metric.write(ws, c, mmv_ver) } @@ -74,9 +84,11 @@ pub fn test() { let mut counter = Counter::new("counter", 1, "", "").unwrap(); assert_eq!(counter.val(), 1); - Client::new("counter_test").unwrap() - .export(&mut [&mut counter]).unwrap(); - + Client::new("counter_test") + .unwrap() + .export(&mut [&mut counter]) + .unwrap(); + counter.up().unwrap(); assert_eq!(counter.val(), 2); diff --git a/src/client/metric/countvector.rs b/src/client/metric/countvector.rs index bf6ab8d..13cf4af 100644 --- a/src/client/metric/countvector.rs +++ b/src/client/metric/countvector.rs @@ -1,5 +1,5 @@ -use std::collections::HashMap; use super::*; +use std::collections::HashMap; /// A count vector for multiple strictly increasing integer values, in possibly /// varying increments @@ -9,42 +9,41 @@ use super::*; pub struct CountVector { im: InstanceMetric, indom: Indom, - init_vals: HashMap + init_vals: HashMap, } impl CountVector { /// Creates a new count vector with given instances and a single initial value - pub fn new(name: &str, init_val: u64, instances: &[&str], - shorthelp_text: &str, longhelp_text: &str) -> Result { - + pub fn new( + name: &str, + init_val: u64, + instances: &[&str], + shorthelp_text: &str, + longhelp_text: &str, + ) -> Result { let mut instances_and_initvals = Vec::new(); for instance in instances { instances_and_initvals.push((*instance, init_val)); } - Self::new_with_initvals( - name, - &instances_and_initvals, - shorthelp_text, - longhelp_text - ) + Self::new_with_initvals(name, &instances_and_initvals, shorthelp_text, longhelp_text) } /// Creates a new count vector with given pairs of an instance and it's initial value - pub fn new_with_initvals(name: &str, instances_and_initvals: &[(&str, u64)], - shorthelp_text: &str, longhelp_text: &str) -> Result { - + pub fn new_with_initvals( + name: &str, + instances_and_initvals: &[(&str, u64)], + shorthelp_text: &str, + longhelp_text: &str, + ) -> Result { let mut instances = Vec::new(); for &(instance, _) in instances_and_initvals.iter() { instances.push(instance); } let indom_helptext = format!("Instance domain for CounterVector '{}'", name); - let indom = Indom::new( - &instances, - &indom_helptext, &indom_helptext - )?; - + let indom = Indom::new(&instances, &indom_helptext, &indom_helptext)?; + let mut im = InstanceMetric::new( &indom, name, @@ -52,7 +51,7 @@ impl CountVector { Semantics::Counter, Unit::new().count(Count::One, 1)?, shorthelp_text, - longhelp_text + longhelp_text, )?; let mut init_vals = HashMap::new(); @@ -64,7 +63,7 @@ impl CountVector { Ok(CountVector { im: im, indom: indom, - init_vals: init_vals + init_vals: init_vals, }) } @@ -77,9 +76,10 @@ impl CountVector { /// /// The wrapping `Option` is `None` if the instance wasn't found pub fn inc(&mut self, instance: &str, increment: u64) -> Option> { - self.im.val(instance).cloned().and_then(|val| - self.im.set_val(instance, val + increment) - ) + self.im + .val(instance) + .cloned() + .and_then(|val| self.im.set_val(instance, val + increment)) } /// Increments the count of the instance by `+1` @@ -108,7 +108,8 @@ impl CountVector { /// /// The wrapping `Option` is `None` if the instance wasn't found pub fn reset(&mut self, instance: &str) -> Option> { - self.im.set_val(instance, *self.init_vals.get(instance).unwrap()) + self.im + .set_val(instance, *self.init_vals.get(instance).unwrap()) } /// Resets the count of all instances to it's initial value that @@ -121,13 +122,20 @@ impl CountVector { } /// Internally created instance domain - pub fn indom(&self) -> &Indom { &self.indom } + pub fn indom(&self) -> &Indom { + &self.indom + } } impl MMVWriter for CountVector { - private_impl!{} - - fn write(&mut self, ws: &mut MMVWriterState, c: &mut Cursor<&mut [u8]>, mmv_ver: Version) -> io::Result<()> { + private_impl! {} + + fn write( + &mut self, + ws: &mut MMVWriterState, + c: &mut Cursor<&mut [u8]>, + mmv_ver: Version, + ) -> io::Result<()> { self.im.write(ws, c, mmv_ver) } @@ -144,20 +152,17 @@ impl MMVWriter for CountVector { pub fn test() { use super::super::Client; - let mut cv = CountVector::new( - "count_vector", - 1, - &["a", "b", "c"], - "", "" - ).unwrap(); + let mut cv = CountVector::new("count_vector", 1, &["a", "b", "c"], "", "").unwrap(); - assert_eq!(cv.val("a").unwrap(), 1); + assert_eq!(cv.val("a").unwrap(), 1); assert_eq!(cv.val("b").unwrap(), 1); assert_eq!(cv.val("c").unwrap(), 1); - Client::new("count_vector_test").unwrap() - .export(&mut [&mut cv]).unwrap(); - + Client::new("count_vector_test") + .unwrap() + .export(&mut [&mut cv]) + .unwrap(); + cv.up("b").unwrap().unwrap(); assert_eq!(cv.val("b").unwrap(), 2); @@ -165,12 +170,12 @@ pub fn test() { assert_eq!(cv.val("c").unwrap(), 4); cv.inc_all(2).unwrap(); - assert_eq!(cv.val("a").unwrap(), 3); + assert_eq!(cv.val("a").unwrap(), 3); assert_eq!(cv.val("b").unwrap(), 4); assert_eq!(cv.val("c").unwrap(), 6); cv.up_all().unwrap(); - assert_eq!(cv.val("a").unwrap(), 4); + assert_eq!(cv.val("a").unwrap(), 4); assert_eq!(cv.val("b").unwrap(), 5); assert_eq!(cv.val("c").unwrap(), 7); @@ -178,7 +183,7 @@ pub fn test() { assert_eq!(cv.val("b").unwrap(), 1); cv.reset_all().unwrap(); - assert_eq!(cv.val("a").unwrap(), 1); + assert_eq!(cv.val("a").unwrap(), 1); assert_eq!(cv.val("b").unwrap(), 1); assert_eq!(cv.val("c").unwrap(), 1); } @@ -190,18 +195,22 @@ pub fn test_multiple_initvals() { let mut cv = CountVector::new_with_initvals( "count_vector_mutiple_initvals", &[("a", 1), ("b", 2), ("c", 3)], - "", "" - ).unwrap(); + "", + "", + ) + .unwrap(); - assert_eq!(cv.val("a").unwrap(), 1); + assert_eq!(cv.val("a").unwrap(), 1); assert_eq!(cv.val("b").unwrap(), 2); assert_eq!(cv.val("c").unwrap(), 3); - Client::new("count_vector_test").unwrap() - .export(&mut [&mut cv]).unwrap(); - + Client::new("count_vector_test") + .unwrap() + .export(&mut [&mut cv]) + .unwrap(); + cv.up_all().unwrap(); - assert_eq!(cv.val("a").unwrap(), 2); + assert_eq!(cv.val("a").unwrap(), 2); assert_eq!(cv.val("b").unwrap(), 3); assert_eq!(cv.val("c").unwrap(), 4); @@ -209,7 +218,7 @@ pub fn test_multiple_initvals() { assert_eq!(cv.val("b").unwrap(), 2); cv.reset_all().unwrap(); - assert_eq!(cv.val("a").unwrap(), 1); + assert_eq!(cv.val("a").unwrap(), 1); assert_eq!(cv.val("b").unwrap(), 2); assert_eq!(cv.val("c").unwrap(), 3); } diff --git a/src/client/metric/gauge.rs b/src/client/metric/gauge.rs index 362d3af..96a2e74 100644 --- a/src/client/metric/gauge.rs +++ b/src/client/metric/gauge.rs @@ -7,24 +7,29 @@ use super::*; /// `Count::One` scale, and `1` count dimension pub struct Gauge { metric: Metric, - init_val: f64 + init_val: f64, } impl Gauge { /// Creates a new gauge metric with given initial value - pub fn new(name: &str, init_val: f64, shorthelp_text: &str, longhelp_text: &str) -> Result { + pub fn new( + name: &str, + init_val: f64, + shorthelp_text: &str, + longhelp_text: &str, + ) -> Result { let metric = Metric::new( name, init_val, Semantics::Instant, Unit::new().count(Count::One, 1)?, shorthelp_text, - longhelp_text + longhelp_text, )?; Ok(Gauge { metric: metric, - init_val: init_val + init_val: init_val, }) } @@ -58,9 +63,14 @@ impl Gauge { } impl MMVWriter for Gauge { - private_impl!{} - - fn write(&mut self, ws: &mut MMVWriterState, c: &mut Cursor<&mut [u8]>, mmv_ver: Version) -> io::Result<()> { + private_impl! {} + + fn write( + &mut self, + ws: &mut MMVWriterState, + c: &mut Cursor<&mut [u8]>, + mmv_ver: Version, + ) -> io::Result<()> { self.metric.write(ws, c, mmv_ver) } @@ -80,9 +90,11 @@ pub fn test() { let mut gauge = Gauge::new("gauge", 1.5, "", "").unwrap(); assert_eq!(gauge.val(), 1.5); - Client::new("gauge_test").unwrap() - .export(&mut [&mut gauge]).unwrap(); - + Client::new("gauge_test") + .unwrap() + .export(&mut [&mut gauge]) + .unwrap(); + gauge.set(3.0).unwrap(); assert_eq!(gauge.val(), 3.0); diff --git a/src/client/metric/gaugevector.rs b/src/client/metric/gaugevector.rs index c2dc379..8372161 100644 --- a/src/client/metric/gaugevector.rs +++ b/src/client/metric/gaugevector.rs @@ -8,17 +8,21 @@ use super::*; pub struct GaugeVector { im: InstanceMetric, indom: Indom, - init_val: f64 + init_val: f64, } impl GaugeVector { /// Creates a new gauge vector with given initial value and instances - pub fn new(name: &str, init_val: f64, instances: &[&str], - shorthelp_text: &str, longhelp_text: &str) -> Result { - + pub fn new( + name: &str, + init_val: f64, + instances: &[&str], + shorthelp_text: &str, + longhelp_text: &str, + ) -> Result { let indom_helptext = format!("Instance domain for GaugeVector '{}'", name); let indom = Indom::new(instances, &indom_helptext, &indom_helptext)?; - + let im = InstanceMetric::new( &indom, name, @@ -26,13 +30,13 @@ impl GaugeVector { Semantics::Counter, Unit::new().count(Count::One, 1)?, shorthelp_text, - longhelp_text + longhelp_text, )?; Ok(GaugeVector { im: im, indom: indom, - init_val: init_val + init_val: init_val, }) } @@ -50,9 +54,10 @@ impl GaugeVector { /// /// The wrapping `Option` is `None` if the instance wasn't found pub fn inc(&mut self, instance: &str, increment: f64) -> Option> { - self.im.val(instance).cloned().and_then(|val| - self.im.set_val(instance, val + increment) - ) + self.im + .val(instance) + .cloned() + .and_then(|val| self.im.set_val(instance, val + increment)) } /// Decrements the gauge of the instance by the given value @@ -94,13 +99,20 @@ impl GaugeVector { } /// Internally created instance domain - pub fn indom(&self) -> &Indom { &self.indom } + pub fn indom(&self) -> &Indom { + &self.indom + } } impl MMVWriter for GaugeVector { - private_impl!{} - - fn write(&mut self, ws: &mut MMVWriterState, c: &mut Cursor<&mut [u8]>, mmv_ver: Version) -> io::Result<()> { + private_impl! {} + + fn write( + &mut self, + ws: &mut MMVWriterState, + c: &mut Cursor<&mut [u8]>, + mmv_ver: Version, + ) -> io::Result<()> { self.im.write(ws, c, mmv_ver) } @@ -117,19 +129,17 @@ impl MMVWriter for GaugeVector { pub fn test() { use super::super::Client; - let mut gv = GaugeVector::new( - "gauge_vector", - 1.5, - &["a", "b", "c"], - "", "").unwrap(); + let mut gv = GaugeVector::new("gauge_vector", 1.5, &["a", "b", "c"], "", "").unwrap(); - assert_eq!(gv.val("a").unwrap(), 1.5); + assert_eq!(gv.val("a").unwrap(), 1.5); assert_eq!(gv.val("b").unwrap(), 1.5); assert_eq!(gv.val("c").unwrap(), 1.5); - Client::new("count_vector_test").unwrap() - .export(&mut [&mut gv]).unwrap(); - + Client::new("count_vector_test") + .unwrap() + .export(&mut [&mut gv]) + .unwrap(); + gv.set("a", 2.5).unwrap().unwrap(); assert_eq!(gv.val("a").unwrap(), 2.5); @@ -140,12 +150,12 @@ pub fn test() { assert_eq!(gv.val("c").unwrap(), 0.0); gv.inc_all(2.0).unwrap(); - assert_eq!(gv.val("a").unwrap(), 4.5); + assert_eq!(gv.val("a").unwrap(), 4.5); assert_eq!(gv.val("b").unwrap(), 5.0); assert_eq!(gv.val("c").unwrap(), 2.0); gv.dec_all(0.5).unwrap(); - assert_eq!(gv.val("a").unwrap(), 4.0); + assert_eq!(gv.val("a").unwrap(), 4.0); assert_eq!(gv.val("b").unwrap(), 4.5); assert_eq!(gv.val("c").unwrap(), 1.5); @@ -153,7 +163,7 @@ pub fn test() { assert_eq!(gv.val("b").unwrap(), 1.5); gv.reset_all().unwrap(); - assert_eq!(gv.val("a").unwrap(), 1.5); + assert_eq!(gv.val("a").unwrap(), 1.5); assert_eq!(gv.val("b").unwrap(), 1.5); assert_eq!(gv.val("c").unwrap(), 1.5); } diff --git a/src/client/metric/histogram.rs b/src/client/metric/histogram.rs index e69d95e..3a8e521 100644 --- a/src/client/metric/histogram.rs +++ b/src/client/metric/histogram.rs @@ -12,7 +12,7 @@ use hdrsample::Histogram as HdrHist; pub struct Histogram { im: InstanceMetric, indom: Indom, - histogram: HdrHist + histogram: HdrHist, } const MAX_INST: &str = "max"; @@ -28,7 +28,7 @@ pub enum CreationError { /// Instance error Instance(String), /// HDR Histogram creation error - HdrHist(hdrsample::CreationError) + HdrHist(hdrsample::CreationError), } impl From for CreationError { @@ -49,7 +49,7 @@ pub enum RecordError { /// IO error Io(io::Error), /// HDR histogram record error - HdrHist(hdrsample::RecordError) + HdrHist(hdrsample::RecordError), } impl From for RecordError { @@ -68,12 +68,18 @@ impl Histogram { /// Creates a new histogram metric /// /// Internally creates a corresponding HDR histogram with auto-resizing disabled - pub fn new(name: &str, low: u64, high: u64, sigfig: u8, unit: Unit, - shorthelp_text: &str, longhelp_text: &str) -> Result { - + pub fn new( + name: &str, + low: u64, + high: u64, + sigfig: u8, + unit: Unit, + shorthelp_text: &str, + longhelp_text: &str, + ) -> Result { let indom_helptext = format!("Instance domain for Histogram '{}'", name); let indom = Indom::new(HIST_INSTANCES, &indom_helptext, &indom_helptext).unwrap(); - + let im = InstanceMetric::new( &indom, name, @@ -81,7 +87,7 @@ impl Histogram { Semantics::Instant, unit, shorthelp_text, - longhelp_text + longhelp_text, )?; let mut histogram = HdrHist::::new_with_bounds(low, high, sigfig)?; @@ -90,13 +96,17 @@ impl Histogram { Ok(Histogram { im: im, indom: indom, - histogram: histogram + histogram: histogram, }) } fn update_instances(&mut self) -> io::Result<()> { - self.im.set_val(MIN_INST, self.histogram.min() as f64).unwrap()?; - self.im.set_val(MAX_INST, self.histogram.max() as f64).unwrap()?; + self.im + .set_val(MIN_INST, self.histogram.min() as f64) + .unwrap()?; + self.im + .set_val(MAX_INST, self.histogram.max() as f64) + .unwrap()?; self.im.set_val(MEAN_INST, self.histogram.mean()).unwrap()?; self.im.set_val(STDEV_INST, self.histogram.stdev()).unwrap() } @@ -122,31 +132,49 @@ impl Histogram { } /// Lowest discernible value - pub fn low(&self) -> u64 { self.histogram.low() } + pub fn low(&self) -> u64 { + self.histogram.low() + } /// Highest trackable value - pub fn high(&self) -> u64 { self.histogram.high() } + pub fn high(&self) -> u64 { + self.histogram.high() + } /// Significant value digits - pub fn significant_figures(&self) -> u8 { self.histogram.sigfig() } + pub fn significant_figures(&self) -> u8 { + self.histogram.sigfig() + } /// Total number of samples recorded so far - pub fn count(&self) -> u64 { self.histogram.count() } + pub fn count(&self) -> u64 { + self.histogram.count() + } /// Number of distinct values that can currently be represented - pub fn len(&self) -> usize { self.histogram.len() } + pub fn len(&self) -> usize { + self.histogram.len() + } /// Lowest recorded value /// /// If no values are yet recorded `0` is returned - pub fn min(&self) -> u64 { self.histogram.min() } + pub fn min(&self) -> u64 { + self.histogram.min() + } /// Highest recorded value /// /// If no values are yet recorded, an undefined value is returned - pub fn max(&self) -> u64 { self.histogram.max() } - + pub fn max(&self) -> u64 { + self.histogram.max() + } + /// Mean of recorded values - pub fn mean(&self) -> f64 { self.histogram.mean() } - + pub fn mean(&self) -> f64 { + self.histogram.mean() + } + /// Standard deviation of recorded values - pub fn stdev(&self) -> f64 { self.histogram.stdev() } + pub fn stdev(&self) -> f64 { + self.histogram.stdev() + } /// Returns corresponding value at percentile pub fn value_at_percentile(&self, percentile: f64) -> u64 { @@ -160,16 +188,25 @@ impl Histogram { } /// Internally created instance domain - pub fn indom(&self) -> &Indom { &self.indom } + pub fn indom(&self) -> &Indom { + &self.indom + } /// Internally created HDR histogram - pub fn hdr_histogram(&self) -> &HdrHist { &self.histogram } + pub fn hdr_histogram(&self) -> &HdrHist { + &self.histogram + } } impl MMVWriter for Histogram { - private_impl!{} - - fn write(&mut self, ws: &mut MMVWriterState, c: &mut Cursor<&mut [u8]>, mmv_ver: Version) -> io::Result<()> { + private_impl! {} + + fn write( + &mut self, + ws: &mut MMVWriterState, + c: &mut Cursor<&mut [u8]>, + mmv_ver: Version, + ) -> io::Result<()> { self.im.write(ws, c, mmv_ver) } @@ -185,49 +222,34 @@ impl MMVWriter for Histogram { #[test] pub fn test() { use super::super::Client; - use rand::{thread_rng, Rng}; use rand::distributions::{IndependentSample, Range}; + use rand::{thread_rng, Rng}; let low = 1; let high = 60 * 60 * 1000; let sigfig = 2; - let mut hist = Histogram::new( - "histogram", - low, high, sigfig, - Unit::new(), - "", "" - ).unwrap(); + let mut hist = Histogram::new("histogram", low, high, sigfig, Unit::new(), "", "").unwrap(); + + Client::new("histogram_test") + .unwrap() + .export(&mut [&mut hist]) + .unwrap(); - Client::new("histogram_test").unwrap() - .export(&mut [&mut hist]).unwrap(); - let val_range = Range::new(low, high); let mut rng = thread_rng(); let n = thread_rng().gen::() % 100; - for _ in 0..n { + for _ in 0..n { hist.record(val_range.ind_sample(&mut rng)).unwrap(); } hist.record_n(val_range.ind_sample(&mut rng), n).unwrap(); - assert_eq!( - *hist.im.val(MIN_INST).unwrap(), - hist.histogram.min() as f64 - ); - - assert_eq!( - *hist.im.val(MAX_INST).unwrap(), - hist.histogram.max() as f64 - ); - - assert_eq!( - *hist.im.val(MEAN_INST).unwrap(), - hist.histogram.mean() - ); - - assert_eq!( - *hist.im.val(STDEV_INST).unwrap(), - hist.histogram.stdev() - ); + assert_eq!(*hist.im.val(MIN_INST).unwrap(), hist.histogram.min() as f64); + + assert_eq!(*hist.im.val(MAX_INST).unwrap(), hist.histogram.max() as f64); + + assert_eq!(*hist.im.val(MEAN_INST).unwrap(), hist.histogram.mean()); + + assert_eq!(*hist.im.val(STDEV_INST).unwrap(), hist.histogram.stdev()); } diff --git a/src/client/metric/mod.rs b/src/client/metric/mod.rs index d999166..8eac27c 100644 --- a/src/client/metric/mod.rs +++ b/src/client/metric/mod.rs @@ -1,29 +1,20 @@ use byteorder::WriteBytesExt; use memmap::{Mmap, MmapViewSync, Protection}; -use std::collections::HashSet; use std::collections::hash_map::{DefaultHasher, HashMap}; use std::collections::hash_set::Iter; +use std::collections::HashSet; use std::fmt; use std::hash::{Hash, Hasher}; use std::io; -use std::io::{Write, Cursor}; +use std::io::{Cursor, Write}; use std::mem; use std::str; use super::super::mmv::{MTCode, Version}; use super::super::{ - Endian, - ITEM_BIT_LEN, - INDOM_BIT_LEN, - STRING_BLOCK_LEN, - VALUE_BLOCK_LEN, - NUMERIC_VALUE_SIZE, - INDOM_BLOCK_LEN, - MMV1_NAME_MAX_LEN, - METRIC_BLOCK_LEN_MMV1, - INSTANCE_BLOCK_LEN_MMV1, - METRIC_BLOCK_LEN_MMV2, - INSTANCE_BLOCK_LEN_MMV2 + Endian, INDOM_BIT_LEN, INDOM_BLOCK_LEN, INSTANCE_BLOCK_LEN_MMV1, INSTANCE_BLOCK_LEN_MMV2, + ITEM_BIT_LEN, METRIC_BLOCK_LEN_MMV1, METRIC_BLOCK_LEN_MMV2, MMV1_NAME_MAX_LEN, + NUMERIC_VALUE_SIZE, STRING_BLOCK_LEN, VALUE_BLOCK_LEN, }; mod counter; @@ -42,8 +33,8 @@ mod gaugevector; pub use self::gaugevector::GaugeVector; mod histogram; -pub use self::histogram::Histogram; pub use self::histogram::CreationError as HistCreationError; +pub use self::histogram::Histogram; pub use self::histogram::RecordError as HistRecordError; mod private { @@ -52,7 +43,7 @@ mod private { /// Generic type for any Metric's value pub trait MetricType { - private_decl!{} + private_decl! {} /// Returns the MMV metric type code fn type_code(&self) -> u32; @@ -66,7 +57,7 @@ mod private { use memmap::MmapViewSync; use std::collections::HashMap; - + pub struct MMVWriterState { // Mmap view of the entier MMV file pub mmap_view: Option, @@ -107,7 +98,7 @@ mod private { // mmv header data pub flags: u32, - pub cluster_id: u32 + pub cluster_id: u32, } impl MMVWriterState { @@ -142,7 +133,7 @@ mod private { string_blk_idx: 0, flags: 0, - cluster_id: 0 + cluster_id: 0, } } } @@ -151,11 +142,14 @@ mod private { /// MMV object that writes blocks to an MMV pub trait MMVWriter { - private_decl!{} + private_decl! {} - fn write(&mut self, + fn write( + &mut self, writer_state: &mut MMVWriterState, - cursor: &mut io::Cursor<&mut [u8]>, mmv_ver: Version) -> io::Result<()>; + cursor: &mut io::Cursor<&mut [u8]>, + mmv_ver: Version, + ) -> io::Result<()>; fn register(&self, ws: &mut MMVWriterState, mmv_ver: Version); @@ -163,8 +157,8 @@ mod private { } } -pub (super) use self::private::MetricType; -pub (super) use self::private::{MMVWriter, MMVWriterState}; +pub(super) use self::private::MetricType; +pub(super) use self::private::{MMVWriter, MMVWriterState}; macro_rules! impl_metric_type_for ( ($typ:tt, $base_typ:tt, $type_code:expr) => ( @@ -197,7 +191,7 @@ impl_metric_type_for!(f32, u32, MTCode::F32); impl_metric_type_for!(f64, u64, MTCode::F64); impl MetricType for String { - private_impl!{} + private_impl! {} fn type_code(&self) -> u32 { MTCode::String as u32 @@ -214,7 +208,7 @@ impl MetricType for String { pub enum Space { /// byte Byte = 0, - /// kilobyte (1024 bytes) + /// kilobyte (1024 bytes) KByte, /// megabyte (1024^2 bytes) MByte, @@ -225,7 +219,7 @@ pub enum Space { /// petabyte (1024^5 bytes) PByte, /// exabyte (1024^6 bytes) - EByte + EByte, } impl Space { @@ -238,7 +232,7 @@ impl Space { 4 => Some(Space::TByte), 5 => Some(Space::PByte), 6 => Some(Space::EByte), - _ => None + _ => None, } } } @@ -252,7 +246,7 @@ impl fmt::Display for Space { Space::GByte => write!(f, "GiB"), Space::TByte => write!(f, "TiB"), Space::PByte => write!(f, "PiB"), - Space::EByte => write!(f, "EiB") + Space::EByte => write!(f, "EiB"), } } } @@ -271,7 +265,7 @@ pub enum Time { /// minute Min, /// hour - Hour + Hour, } impl Time { @@ -283,7 +277,7 @@ impl Time { 3 => Some(Time::Sec), 4 => Some(Time::Min), 5 => Some(Time::Hour), - _ => None + _ => None, } } } @@ -304,14 +298,14 @@ impl fmt::Display for Time { #[derive(Copy, Clone)] /// Scale for the count component of a unit pub enum Count { - One = 0 + One = 0, } impl Count { fn from_u8(x: u8) -> Option { match x { 0 => Some(Count::One), - _ => None + _ => None, } } } @@ -319,7 +313,7 @@ impl Count { impl fmt::Display for Count { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - Count::One => write!(f, "count") + Count::One => write!(f, "count"), } } } @@ -337,7 +331,7 @@ pub struct Unit { 11 - 8 : count scale (unsigned) 7 - 0 : zero pad */ - pmapi_repr: u32 + pmapi_repr: u32, } const SPACE_DIM_LSB: u8 = 28; @@ -361,7 +355,7 @@ impl Unit { /// Returns a unit constructed from a raw PMAPI representation pub fn from_raw(pmapi_repr: u32) -> Self { Unit { - pmapi_repr: pmapi_repr + pmapi_repr: pmapi_repr, } } @@ -419,10 +413,7 @@ impl Unit { to an i32 before we right shift it. */ fn dim(&self, lsb: u8) -> i8 { - ( - ( self.pmapi_repr << (32 - (lsb + 4)) ) as i32 - >> 28 - ) as i8 + ((self.pmapi_repr << (32 - (lsb + 4))) as i32 >> 28) as i8 } fn space_dim(&self) -> i8 { @@ -490,11 +481,11 @@ impl fmt::Display for Unit { /// Semantic for a Metric pub enum Semantics { /// Counter - Counter = 1, + Counter = 1, /// Instant - Instant = 3, + Instant = 3, /// Discrete - Discrete = 4 + Discrete = 4, } impl Semantics { @@ -503,7 +494,7 @@ impl Semantics { 1 => Some(Semantics::Counter), 3 => Some(Semantics::Instant), 4 => Some(Semantics::Discrete), - _ => None + _ => None, } } } @@ -513,7 +504,7 @@ impl fmt::Display for Semantics { match *self { Semantics::Counter => write!(f, "counter")?, Semantics::Instant => write!(f, "instant")?, - Semantics::Discrete => write!(f, "discrete")? + Semantics::Discrete => write!(f, "discrete")?, } write!(f, " (0x{:x})", *self as u32) } @@ -529,12 +520,13 @@ pub struct Metric { shorthelp: String, longhelp: String, val: T, - mmap_view: MmapViewSync + mmap_view: MmapViewSync, } lazy_static! { static ref SCRATCH_VIEW: MmapViewSync = { - Mmap::anonymous(STRING_BLOCK_LEN as usize, Protection::ReadWrite).unwrap() + Mmap::anonymous(STRING_BLOCK_LEN as usize, Protection::ReadWrite) + .unwrap() .into_view_sync() }; } @@ -545,17 +537,27 @@ impl Metric { /// The result is an error if the length of `name`, `shorthelp` /// or `longhelp` exceed 255 bytes. pub fn new( - name: &str, init_val: T, sem: Semantics, unit: Unit, - shorthelp: &str, longhelp: &str) -> Result { - + name: &str, + init_val: T, + sem: Semantics, + unit: Unit, + shorthelp: &str, + longhelp: &str, + ) -> Result { if name.len() >= STRING_BLOCK_LEN as usize { return Err(format!("name longer than {} bytes", STRING_BLOCK_LEN - 1)); } if shorthelp.len() >= STRING_BLOCK_LEN as usize { - return Err(format!("short help text longer than {} bytes", STRING_BLOCK_LEN - 1)); + return Err(format!( + "short help text longer than {} bytes", + STRING_BLOCK_LEN - 1 + )); } if longhelp.len() >= STRING_BLOCK_LEN as usize { - return Err(format!("long help text longer than {} bytes", STRING_BLOCK_LEN - 1)); + return Err(format!( + "long help text longer than {} bytes", + STRING_BLOCK_LEN - 1 + )); } let mut hasher = DefaultHasher::new(); @@ -571,14 +573,14 @@ impl Metric { shorthelp: shorthelp.to_owned(), longhelp: longhelp.to_owned(), val: init_val, - mmap_view: unsafe { SCRATCH_VIEW.clone() } + mmap_view: unsafe { SCRATCH_VIEW.clone() }, }) } /// Returns the current value of the metric pub fn val(&self) -> &T { &self.val - } + } /// Sets the current value of the metric. /// @@ -592,15 +594,31 @@ impl Metric { self.val = new_val; Ok(()) } - - pub fn name(&self) -> &str { &self.name } - pub fn item(&self) -> u32 { self.item } - pub fn type_code(&self) -> u32 { self.val.type_code() } - pub fn sem(&self) -> &Semantics { &self.sem } - pub fn unit(&self) -> u32 { self.unit } - pub fn indom(&self) -> u32 { self.indom } - pub fn shorthelp(&self) -> &str { &self.shorthelp } - pub fn longhelp(&self) -> &str { &self.longhelp } + + pub fn name(&self) -> &str { + &self.name + } + pub fn item(&self) -> u32 { + self.item + } + pub fn type_code(&self) -> u32 { + self.val.type_code() + } + pub fn sem(&self) -> &Semantics { + &self.sem + } + pub fn unit(&self) -> u32 { + self.unit + } + pub fn indom(&self) -> u32 { + self.indom + } + pub fn shorthelp(&self) -> &str { + &self.shorthelp + } + pub fn longhelp(&self) -> &str { + &self.longhelp + } } #[derive(Clone)] @@ -609,7 +627,7 @@ pub struct Indom { instances: HashSet, id: u32, shorthelp: String, - longhelp: String + longhelp: String, } impl Indom { @@ -623,21 +641,30 @@ impl Indom { for instance in instances { if instance.len() >= STRING_BLOCK_LEN as usize { - return Err(format!("instance longer than {} bytes", STRING_BLOCK_LEN - 1)); + return Err(format!( + "instance longer than {} bytes", + STRING_BLOCK_LEN - 1 + )); } } if shorthelp.len() >= STRING_BLOCK_LEN as usize { - return Err(format!("short help text longer than {} bytes", STRING_BLOCK_LEN - 1)); + return Err(format!( + "short help text longer than {} bytes", + STRING_BLOCK_LEN - 1 + )); } if longhelp.len() >= STRING_BLOCK_LEN as usize { - return Err(format!("long help text longer than {} bytes", STRING_BLOCK_LEN - 1)); + return Err(format!( + "long help text longer than {} bytes", + STRING_BLOCK_LEN - 1 + )); } Ok(Indom { instances: instances.into_iter().map(|inst| inst.to_string()).collect(), id: (hasher.finish() as u32) & ((1 << INDOM_BIT_LEN) - 1), shorthelp: shorthelp.to_owned(), - longhelp: longhelp.to_owned() + longhelp: longhelp.to_owned(), }) } @@ -657,8 +684,12 @@ impl Indom { self.instances.iter() } - pub fn shorthelp(&self) -> &str { &self.shorthelp } - pub fn longhelp(&self) -> &str { &self.longhelp } + pub fn shorthelp(&self) -> &str { + &self.shorthelp + } + pub fn longhelp(&self) -> &str { + &self.longhelp + } fn instance_id(instance: &str) -> u32 { let mut hasher = DefaultHasher::new(); @@ -667,15 +698,15 @@ impl Indom { } fn has_mmv2_string(&self) -> bool { - self.instances.iter().any(|instance| - instance.len() >= MMV1_NAME_MAX_LEN as usize - ) + self.instances + .iter() + .any(|instance| instance.len() >= MMV1_NAME_MAX_LEN as usize) } } struct Instance { val: T, - mmap_view: MmapViewSync + mmap_view: MmapViewSync, } /// An instance metric is a set of related metrics with same @@ -684,7 +715,7 @@ struct Instance { pub struct InstanceMetric { indom: Indom, vals: HashMap>, - metric: Metric + metric: Metric, } impl InstanceMetric { @@ -699,26 +730,24 @@ impl InstanceMetric { sem: Semantics, unit: Unit, shorthelp: &str, - longhelp: &str) -> Result { - + longhelp: &str, + ) -> Result { let mut vals = HashMap::with_capacity(indom.instances.len()); for instance_str in &indom.instances { let instance = Instance { val: init_val.clone(), - mmap_view: unsafe { SCRATCH_VIEW.clone() } + mmap_view: unsafe { SCRATCH_VIEW.clone() }, }; vals.insert(instance_str.to_owned(), instance); } - let mut metric = Metric::new( - name, init_val.clone(), sem, unit, shorthelp, longhelp - )?; + let mut metric = Metric::new(name, init_val.clone(), sem, unit, shorthelp, longhelp)?; metric.indom = indom.id; - + Ok(InstanceMetric { indom: indom.clone(), vals: vals, - metric: metric + metric: metric, }) } @@ -739,7 +768,7 @@ impl InstanceMetric { /// Sets the value of the given instance. If the instance isn't /// found, returns `None`. - pub fn set_val(&mut self, instance: &str, new_val: T) -> Option> { + pub fn set_val(&mut self, instance: &str, new_val: T) -> Option> { self.vals.get_mut(instance).map(|i| { new_val.write(unsafe { &mut i.mmap_view.as_mut_slice() })?; i.val = new_val; @@ -747,27 +776,39 @@ impl InstanceMetric { }) } - pub fn name(&self) -> &str { &self.metric.name } - pub fn sem(&self) -> &Semantics { &self.metric.sem } - pub fn unit(&self) -> u32 { self.metric.unit } - pub fn shorthelp(&self) -> &str { &self.metric.shorthelp } - pub fn longhelp(&self) -> &str { &self.metric.longhelp } + pub fn name(&self) -> &str { + &self.metric.name + } + pub fn sem(&self) -> &Semantics { + &self.metric.sem + } + pub fn unit(&self) -> u32 { + self.metric.unit + } + pub fn shorthelp(&self) -> &str { + &self.metric.shorthelp + } + pub fn longhelp(&self) -> &str { + &self.metric.longhelp + } } impl Metric { - fn write_to_mmv(&mut self, ws: &mut MMVWriterState, c: &mut Cursor<&mut [u8]>, - mmv_ver: Version, write_value_blk: bool) -> io::Result { - + fn write_to_mmv( + &mut self, + ws: &mut MMVWriterState, + c: &mut Cursor<&mut [u8]>, + mmv_ver: Version, + write_value_blk: bool, + ) -> io::Result { let orig_pos = c.position(); // metric block let metric_blk_len = match mmv_ver { Version::V1 => METRIC_BLOCK_LEN_MMV1, - Version::V2 => METRIC_BLOCK_LEN_MMV2 + Version::V2 => METRIC_BLOCK_LEN_MMV2, }; - let metric_blk_off = - ws.metric_sec_off - + metric_blk_len*ws.metric_blk_idx; + let metric_blk_off = ws.metric_sec_off + metric_blk_len * ws.metric_blk_idx; c.set_position(metric_blk_off); // name @@ -776,7 +817,7 @@ impl Metric { c.write_all(self.name.as_bytes())?; c.write_all(&[0])?; c.set_position(metric_blk_off + MMV1_NAME_MAX_LEN); - }, + } Version::V2 => { let name_off = write_mmv_string(ws, c, &self.name, false)?; c.write_u64::(name_off)?; @@ -806,11 +847,8 @@ impl Metric { let (value_offset, value_size) = write_value_block(ws, c, &self.val, metric_blk_off, 0)?; - let mmap_view = unsafe { - ws.mmap_view.as_mut().unwrap().clone() - }; - let (_, value_mmap_view, _) = - three_way_split(mmap_view, value_offset, value_size)?; + let mmap_view = unsafe { ws.mmap_view.as_mut().unwrap().clone() }; + let (_, value_mmap_view, _) = three_way_split(mmap_view, value_offset, value_size)?; self.mmap_view = value_mmap_view; } @@ -821,9 +859,14 @@ impl Metric { } impl MMVWriter for Metric { - private_impl!{} - - fn write(&mut self, ws: &mut MMVWriterState, c: &mut Cursor<&mut [u8]>, mmv_ver: Version) -> io::Result<()> { + private_impl! {} + + fn write( + &mut self, + ws: &mut MMVWriterState, + c: &mut Cursor<&mut [u8]>, + mmv_ver: Version, + ) -> io::Result<()> { self.write_to_mmv(ws, c, mmv_ver, true)?; Ok(()) } @@ -840,8 +883,8 @@ impl MMVWriter for Metric { cache_and_register_string(ws, &self.longhelp); match mmv_ver { - Version::V1 => {}, - Version::V2 => cache_and_register_string(ws, &self.name) + Version::V1 => {} + Version::V2 => cache_and_register_string(ws, &self.name), } } @@ -851,9 +894,14 @@ impl MMVWriter for Metric { } impl MMVWriter for InstanceMetric { - private_impl!{} - - fn write(&mut self, ws: &mut MMVWriterState, c: &mut Cursor<&mut [u8]>, mmv_ver: Version) -> io::Result<()> { + private_impl! {} + + fn write( + &mut self, + ws: &mut MMVWriterState, + c: &mut Cursor<&mut [u8]>, + mmv_ver: Version, + ) -> io::Result<()> { // write metric block let metric_blk_off = self.metric.write_to_mmv(ws, c, mmv_ver, false)?; @@ -862,19 +910,14 @@ impl MMVWriter for InstanceMetric { // write value blocks for (instance_name, instance) in self.vals.iter_mut() { - let instance_blk_off = *instance_blk_offs.get(instance_name).unwrap(); let (value_offset, value_size) = write_value_block(ws, c, &instance.val, metric_blk_off, instance_blk_off)?; // set mmap_view for instance - let mmap_view = unsafe { - ws.mmap_view.as_mut().unwrap().clone() - }; - let (_, value_mmap_view, _) = - three_way_split(mmap_view, value_offset, value_size)?; + let mmap_view = unsafe { ws.mmap_view.as_mut().unwrap().clone() }; + let (_, value_mmap_view, _) = three_way_split(mmap_view, value_offset, value_size)?; instance.mmap_view = value_mmap_view; - } Ok(()) @@ -899,7 +942,7 @@ impl MMVWriter for InstanceMetric { ws.indom_cache.insert(self.indom.id, None); match mmv_ver { - Version::V1 => {}, + Version::V1 => {} Version::V2 => { cache_and_register_string(ws, &self.metric.name); for instance in &self.indom.instances { @@ -915,20 +958,21 @@ impl MMVWriter for InstanceMetric { } } -fn write_indom_and_instances<'a>(ws: &mut MMVWriterState, c: &mut Cursor<&mut [u8]>, - indom: &Indom, mmv_ver: Version)-> io::Result> { - +fn write_indom_and_instances<'a>( + ws: &mut MMVWriterState, + c: &mut Cursor<&mut [u8]>, + indom: &Indom, + mmv_ver: Version, +) -> io::Result> { // write each indom and it's instances only once if let Some(blk_offs) = ws.indom_cache.get(&indom.id) { if let &Some(ref blk_offs) = blk_offs { - return Ok(blk_offs.clone()) + return Ok(blk_offs.clone()); } } // write indom block - let indom_off = - ws.indom_sec_off - + INDOM_BLOCK_LEN*ws.indom_idx; + let indom_off = ws.indom_sec_off + INDOM_BLOCK_LEN * ws.indom_idx; c.set_position(indom_off); // indom id c.write_u32::(indom.id)?; @@ -938,11 +982,9 @@ fn write_indom_and_instances<'a>(ws: &mut MMVWriterState, c: &mut Cursor<&mut [u // offset to instances let instance_blk_len = match mmv_ver { Version::V1 => INSTANCE_BLOCK_LEN_MMV1, - Version::V2 => INSTANCE_BLOCK_LEN_MMV2 + Version::V2 => INSTANCE_BLOCK_LEN_MMV2, }; - let mut instance_blk_off = - ws.instance_sec_off - + instance_blk_len*ws.instance_idx; + let mut instance_blk_off = ws.instance_sec_off + instance_blk_len * ws.instance_idx; c.write_u64::(instance_blk_off)?; // short help @@ -969,7 +1011,7 @@ fn write_indom_and_instances<'a>(ws: &mut MMVWriterState, c: &mut Cursor<&mut [u Version::V1 => { c.write_all(instance.as_bytes())?; c.write_all(&[0])?; - }, + } Version::V2 => { let instance_off = write_mmv_string(ws, c, instance, false)?; c.write_u64::(instance_off)?; @@ -988,7 +1030,11 @@ fn write_indom_and_instances<'a>(ws: &mut MMVWriterState, c: &mut Cursor<&mut [u Ok(cloned_offs) } -fn three_way_split(view: MmapViewSync, mid_idx: usize, mid_len: usize) -> io::Result<(MmapViewSync, MmapViewSync, MmapViewSync)> { +fn three_way_split( + view: MmapViewSync, + mid_idx: usize, + mid_len: usize, +) -> io::Result<(MmapViewSync, MmapViewSync, MmapViewSync)> { let (left_view, mid_right_view) = view.split_at(mid_idx).unwrap(); let (mid_view, right_view) = mid_right_view.split_at(mid_len).unwrap(); Ok((left_view, mid_view, right_view)) @@ -998,15 +1044,16 @@ fn three_way_split(view: MmapViewSync, mid_idx: usize, mid_len: usize) -> io::Re // and returns the offset `val` was written at and it's size - (offset, size) // // leaves the cursor in the original position it was at when passed -fn write_value_block(ws: &mut MMVWriterState, - mut c: &mut Cursor<&mut [u8]>, value: &T, - metric_blk_off: u64, instance_blk_off: u64) -> io::Result<(usize, usize)> { - +fn write_value_block( + ws: &mut MMVWriterState, + mut c: &mut Cursor<&mut [u8]>, + value: &T, + metric_blk_off: u64, + instance_blk_off: u64, +) -> io::Result<(usize, usize)> { let orig_pos = c.position(); - let value_blk_off = - ws.value_sec_off - + ws.value_blk_idx*VALUE_BLOCK_LEN; + let value_blk_off = ws.value_sec_off + ws.value_blk_idx * VALUE_BLOCK_LEN; ws.value_blk_idx += 1; c.set_position(value_blk_off); @@ -1043,7 +1090,7 @@ fn write_value_block(ws: &mut MMVWriterState, c.write_u64::(metric_blk_off)?; // offset to instance block c.write_u64::(instance_blk_off)?; - + c.set_position(orig_pos); Ok((value_offset, value_size)) } @@ -1061,19 +1108,20 @@ fn cache_and_register_string(ws: &mut MMVWriterState, string: &str) { // leaves the cursor in the original position it was at when passed // // when writing first string in MMV, also writes the string TOC block -fn write_mmv_string(ws: &mut MMVWriterState, - c: &mut Cursor<&mut [u8]>, string: &str, is_value: bool) -> io::Result { - +fn write_mmv_string( + ws: &mut MMVWriterState, + c: &mut Cursor<&mut [u8]>, + string: &str, + is_value: bool, +) -> io::Result { if string.len() == 0 { return Ok(0); } let orig_pos = c.position(); - let string_block_off = - ws.string_sec_off - + STRING_BLOCK_LEN*ws.string_blk_idx; - + let string_block_off = ws.string_sec_off + STRING_BLOCK_LEN * ws.string_blk_idx; + // only cache if the string is not a value if !is_value { if let Some(cached_offset) = ws.non_value_string_cache.get(string).clone() { @@ -1082,7 +1130,8 @@ fn write_mmv_string(ws: &mut MMVWriterState, } } - ws.non_value_string_cache.insert(string.to_owned(), Some(string_block_off)); + ws.non_value_string_cache + .insert(string.to_owned(), Some(string_block_off)); } // write string in string section @@ -1103,8 +1152,9 @@ fn test_instance_metrics() { let caches = Indom::new( &["L1", "L2", "L3"], "Caches", - "Different levels of CPU caches" - ).unwrap(); + "Different levels of CPU caches", + ) + .unwrap(); let mut cache_sizes = InstanceMetric::new( &caches, @@ -1113,8 +1163,9 @@ fn test_instance_metrics() { Semantics::Discrete, Unit::new().space(Space::KByte, 1).unwrap(), "Cache sizes", - "Sizes of different CPU caches" - ).unwrap(); + "Sizes of different CPU caches", + ) + .unwrap(); assert!(cache_sizes.has_instance("L1")); assert!(!cache_sizes.has_instance("L4")); @@ -1127,15 +1178,19 @@ fn test_instance_metrics() { String::from("kabylake"), Semantics::Discrete, Unit::new(), - "CPU family", "", - ).unwrap(); + "CPU family", + "", + ) + .unwrap(); - Client::new("system").unwrap() - .export(&mut [&mut cache_sizes, &mut cpu]).unwrap(); + Client::new("system") + .unwrap() + .export(&mut [&mut cache_sizes, &mut cpu]) + .unwrap(); assert!(cache_sizes.set_val("L3", 8192).is_some()); assert_eq!(*cache_sizes.val("L3").unwrap(), 8192); - + assert!(cache_sizes.set_val("L4", 16384).is_none()); } @@ -1158,17 +1213,21 @@ fn test_units() { let (space_dim, time_dim, count_dim) = (-3, -2, 1); let unit = Unit::new() - .space(Space::EByte, space_dim).unwrap() - .time(Time::Hour, time_dim).unwrap() - .count(Count::One, count_dim).unwrap(); - - assert_eq!(unit.pmapi_repr, - ((space_dim as u32) & ((1 << 4) - 1)) << 28 | - ((time_dim as u32) & ((1 << 4) - 1)) << 24 | - ((count_dim as u32) & ((1 << 4) - 1)) << 20 | - (Space::EByte as u32) << 16 | - (Time::Hour as u32) << 12 | - (Count::One as u32) << 8 + .space(Space::EByte, space_dim) + .unwrap() + .time(Time::Hour, time_dim) + .unwrap() + .count(Count::One, count_dim) + .unwrap(); + + assert_eq!( + unit.pmapi_repr, + ((space_dim as u32) & ((1 << 4) - 1)) << 28 + | ((time_dim as u32) & ((1 << 4) - 1)) << 24 + | ((count_dim as u32) & ((1 << 4) - 1)) << 20 + | (Space::EByte as u32) << 16 + | (Time::Hour as u32) << 12 + | (Count::One as u32) << 8 ); assert!(Unit::new().space(Space::Byte, 8).is_err()); @@ -1178,43 +1237,27 @@ fn test_units() { #[test] fn test_invalid_strings() { use rand::{thread_rng, Rng}; - + let sem = Semantics::Discrete; let unit = Unit::new(); - let invalid_string: String = thread_rng().gen_ascii_chars() - .take(STRING_BLOCK_LEN as usize).collect(); - - assert!(Metric::new( - &invalid_string, 0, sem, unit, "", "" - ).is_err()); - assert!(Metric::new( - "", 0, sem, unit, &invalid_string, "" - ).is_err()); - assert!(Metric::new( - "", 0, sem, unit, "", &invalid_string - ).is_err()); - - assert!(Indom::new( - &[&invalid_string], "", "" - ).is_err()); - assert!(Indom::new( - &[], &invalid_string, "" - ).is_err()); - assert!(Indom::new( - &[], "", &invalid_string, - ).is_err()); + let invalid_string: String = thread_rng() + .gen_ascii_chars() + .take(STRING_BLOCK_LEN as usize) + .collect(); + + assert!(Metric::new(&invalid_string, 0, sem, unit, "", "").is_err()); + assert!(Metric::new("", 0, sem, unit, &invalid_string, "").is_err()); + assert!(Metric::new("", 0, sem, unit, "", &invalid_string).is_err()); + + assert!(Indom::new(&[&invalid_string], "", "").is_err()); + assert!(Indom::new(&[], &invalid_string, "").is_err()); + assert!(Indom::new(&[], "", &invalid_string,).is_err()); let indom = Indom::new(&[], "", "").unwrap(); - assert!(InstanceMetric::new( - &indom, &invalid_string, 0, sem, unit, "", "" - ).is_err()); - assert!(InstanceMetric::new( - &indom, "", 0, sem, unit, &invalid_string, "" - ).is_err()); - assert!(InstanceMetric::new( - &indom, "", 0, sem, unit, "", &invalid_string - ).is_err()); + assert!(InstanceMetric::new(&indom, &invalid_string, 0, sem, unit, "", "").is_err()); + assert!(InstanceMetric::new(&indom, "", 0, sem, unit, &invalid_string, "").is_err()); + assert!(InstanceMetric::new(&indom, "", 0, sem, unit, "", &invalid_string).is_err()); } #[test] @@ -1224,10 +1267,14 @@ fn test_mmv2_string_check() { let sem = Semantics::Discrete; let unit = Unit::new(); - let mmv1_string: String = thread_rng().gen_ascii_chars() - .take((MMV1_NAME_MAX_LEN - 1) as usize).collect(); - let mmv2_string: String = thread_rng().gen_ascii_chars() - .take((STRING_BLOCK_LEN - 1) as usize).collect(); + let mmv1_string: String = thread_rng() + .gen_ascii_chars() + .take((MMV1_NAME_MAX_LEN - 1) as usize) + .collect(); + let mmv2_string: String = thread_rng() + .gen_ascii_chars() + .take((STRING_BLOCK_LEN - 1) as usize) + .collect(); let mmv1_metric = Metric::new(&mmv1_string, 0, sem, unit, "", "").unwrap(); assert_eq!(mmv1_metric.has_mmv2_string(), false); @@ -1252,14 +1299,16 @@ fn test_mmv2_string_check() { #[test] fn test_mmv2_string_blocks() { use super::super::mmv::*; - use rand::{thread_rng, Rng}; use super::Client; + use rand::{thread_rng, Rng}; let sem = Semantics::Discrete; let unit = Unit::new(); - let mmv2_string: String = thread_rng().gen_ascii_chars() - .take((STRING_BLOCK_LEN - 1) as usize).collect(); + let mmv2_string: String = thread_rng() + .gen_ascii_chars() + .take((STRING_BLOCK_LEN - 1) as usize) + .collect(); let mut metric = Metric::new(&mmv2_string, 0, sem, unit, "", "").unwrap(); let indom = Indom::new(&[&mmv2_string], "", "").unwrap(); @@ -1269,11 +1318,12 @@ fn test_mmv2_string_blocks() { client.export(&mut [&mut metric, &mut im]).unwrap(); let mmv = dump(client.mmv_path()).unwrap(); - + for m_blk in mmv.metric_blks().values() { match m_blk.name() { - &VersionSpecificString::String(ref s) => - panic!("metric name \"{}\" should be in string section", s), + &VersionSpecificString::String(ref s) => { + panic!("metric name \"{}\" should be in string section", s) + } &VersionSpecificString::Offset(ref off) => { let string = mmv.string_blks().get(off).unwrap().string(); assert_eq!(string, mmv2_string); @@ -1283,8 +1333,9 @@ fn test_mmv2_string_blocks() { for i_blk in mmv.instance_blks().values() { match i_blk.external_id() { - &VersionSpecificString::String(ref s) => - panic!("instance \"{}\" should be in string section", s), + &VersionSpecificString::String(ref s) => { + panic!("instance \"{}\" should be in string section", s) + } &VersionSpecificString::Offset(ref off) => { let string = mmv.string_blks().get(off).unwrap().string(); assert_eq!(string, mmv2_string); @@ -1295,25 +1346,31 @@ fn test_mmv2_string_blocks() { #[test] fn test_random_numeric_metrics() { + use super::Client; use byteorder::ReadBytesExt; use rand::{thread_rng, Rng}; - use super::Client; let mut metrics = Vec::new(); let mut new_vals = Vec::new(); let n_metrics = thread_rng().gen::() % 20; let client = Client::new("numeric_metrics").unwrap(); - + for _ in 1..n_metrics { - let rnd_name: String = thread_rng().gen_ascii_chars() - .take(MMV1_NAME_MAX_LEN as usize - 1).collect(); + let rnd_name: String = thread_rng() + .gen_ascii_chars() + .take(MMV1_NAME_MAX_LEN as usize - 1) + .collect(); - let rnd_shorthelp: String = thread_rng().gen_ascii_chars() - .take(STRING_BLOCK_LEN as usize - 1).collect(); + let rnd_shorthelp: String = thread_rng() + .gen_ascii_chars() + .take(STRING_BLOCK_LEN as usize - 1) + .collect(); - let rnd_longhelp: String = thread_rng().gen_ascii_chars() - .take(STRING_BLOCK_LEN as usize - 1).collect(); + let rnd_longhelp: String = thread_rng() + .gen_ascii_chars() + .take(STRING_BLOCK_LEN as usize - 1) + .collect(); let rnd_val1 = thread_rng().gen::(); @@ -1324,7 +1381,8 @@ fn test_random_numeric_metrics() { Unit::new(), &rnd_shorthelp, &rnd_longhelp, - ).unwrap(); + ) + .unwrap(); assert_eq!(*metric.val(), rnd_val1); @@ -1336,12 +1394,12 @@ fn test_random_numeric_metrics() { new_vals.push(thread_rng().gen::()); } - { // mmv_writers needs to go out of scope before we can mutate - // the metrics after exporting. The type annotation is needed - // because type inference fails. - let mut mmv_writers: Vec<&mut MMVWriter> = metrics.iter_mut() - .map(|m| m as &mut MMVWriter) - .collect(); + { + // mmv_writers needs to go out of scope before we can mutate + // the metrics after exporting. The type annotation is needed + // because type inference fails. + let mut mmv_writers: Vec<&mut MMVWriter> = + metrics.iter_mut().map(|m| m as &mut MMVWriter).collect(); client.export(&mut mmv_writers).unwrap(); } @@ -1357,11 +1415,11 @@ fn test_random_numeric_metrics() { #[test] fn test_simple_metrics() { + use super::Client; use byteorder::ReadBytesExt; use rand::{thread_rng, Rng}; use std::ffi::CStr; use std::mem::transmute; - use super::Client; // f64 metric let hz = Unit::new().time(Time::Sec, -1).unwrap(); @@ -1370,8 +1428,10 @@ fn test_simple_metrics() { thread_rng().gen::(), Semantics::Instant, hz, - "", "", - ).unwrap(); + "", + "", + ) + .unwrap(); // string metric let mut color = Metric::new( @@ -1379,8 +1439,10 @@ fn test_simple_metrics() { String::from("cyan"), Semantics::Discrete, Unit::new(), - "Color", "", - ).unwrap(); + "Color", + "", + ) + .unwrap(); // u32 metric let mut photons = Metric::new( @@ -1390,10 +1452,13 @@ fn test_simple_metrics() { Unit::new().count(Count::One, 1).unwrap(), "No. of photons", "Number of photons emitted by source", - ).unwrap(); + ) + .unwrap(); - Client::new("physical_metrics").unwrap() - .export(&mut [&mut freq, &mut color, &mut photons]).unwrap(); + Client::new("physical_metrics") + .unwrap() + .export(&mut [&mut freq, &mut color, &mut photons]) + .unwrap(); let new_freq = thread_rng().gen::(); assert!(freq.set_val(new_freq).is_ok()); @@ -1405,17 +1470,12 @@ fn test_simple_metrics() { assert!(photons.set_val(new_photon_count).is_ok()); let mut freq_slice = unsafe { freq.mmap_view.as_slice() }; - assert_eq!( - new_freq, - unsafe { - transmute::(freq_slice.read_u64::().unwrap()) - } - ); + assert_eq!(new_freq, unsafe { + transmute::(freq_slice.read_u64::().unwrap()) + }); let color_slice = unsafe { color.mmap_view.as_slice() }; - let cstr = unsafe { - CStr::from_ptr(color_slice.as_ptr() as *const i8) - }; + let cstr = unsafe { CStr::from_ptr(color_slice.as_ptr() as *const i8) }; assert_eq!(new_color, cstr.to_str().unwrap()); let mut photon_slice = unsafe { photons.mmap_view.as_slice() }; diff --git a/src/client/metric/timer.rs b/src/client/metric/timer.rs index 4257354..24e83ef 100644 --- a/src/client/metric/timer.rs +++ b/src/client/metric/timer.rs @@ -8,7 +8,7 @@ use time::Tm; pub struct Timer { metric: Metric, time_scale: Time, - start_time: Option + start_time: Option, } /// Error encountered while starting or stopping a timer @@ -30,22 +30,25 @@ impl From for Error { impl Timer { /// Creates a new timer metric with given time scale - pub fn new(name: &str, time_scale: Time, - shorthelp_text: &str, longhelp_text: &str) -> Result { - + pub fn new( + name: &str, + time_scale: Time, + shorthelp_text: &str, + longhelp_text: &str, + ) -> Result { let metric = Metric::new( name, 0, Semantics::Instant, Unit::new().time(time_scale, 1)?, shorthelp_text, - longhelp_text + longhelp_text, )?; Ok(Timer { metric: metric, time_scale: time_scale, - start_time: None + start_time: None, }) } @@ -53,7 +56,7 @@ impl Timer { /// already started. pub fn start(&mut self) -> Result<(), Error> { if self.start_time.is_some() { - return Err(Error::TimerAlreadyStarted) + return Err(Error::TimerAlreadyStarted); } self.start_time = Some(time::now()); Ok(()) @@ -75,7 +78,7 @@ impl Timer { Time::MSec => duration.num_microseconds().unwrap_or(0), Time::Sec => duration.num_seconds(), Time::Min => duration.num_minutes(), - Time::Hour => duration.num_hours() + Time::Hour => duration.num_hours(), }; let val = *self.metric.val(); @@ -88,8 +91,8 @@ impl Timer { } Ok(elapsed) - }, - None => Err(Error::TimerNotStarted) + } + None => Err(Error::TimerNotStarted), } } @@ -101,9 +104,14 @@ impl Timer { } impl MMVWriter for Timer { - private_impl!{} - - fn write(&mut self, ws: &mut MMVWriterState, c: &mut Cursor<&mut [u8]>, mmv_ver: Version) -> io::Result<()> { + private_impl! {} + + fn write( + &mut self, + ws: &mut MMVWriterState, + c: &mut Cursor<&mut [u8]>, + mmv_ver: Version, + ) -> io::Result<()> { self.metric.write(ws, c, mmv_ver) } @@ -125,11 +133,13 @@ pub fn test() { let mut timer = Timer::new("timer", Time::MSec, "", "").unwrap(); assert_eq!(timer.elapsed(), 0); - Client::new("timer_test").unwrap() - .export(&mut [&mut timer]).unwrap(); + Client::new("timer_test") + .unwrap() + .export(&mut [&mut timer]) + .unwrap(); assert!(timer.stop().is_err()); - + let sleep_time = 2; // seconds timer.start().unwrap(); diff --git a/src/client/mod.rs b/src/client/mod.rs index 0a3a555..94e65e0 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -7,25 +7,17 @@ use std::fmt; use std::fs; use std::fs::{File, OpenOptions}; use std::io; -use std::io::{BufReader, Cursor}; use std::io::prelude::*; -use std::path::{MAIN_SEPARATOR, Path, PathBuf}; +use std::io::{BufReader, Cursor}; +use std::path::{Path, PathBuf, MAIN_SEPARATOR}; use std::str; use time; use super::mmv::Version; use super::{ - Endian, - CLUSTER_ID_BIT_LEN, - HDR_LEN, - TOC_BLOCK_LEN, - VALUE_BLOCK_LEN, - STRING_BLOCK_LEN, - INDOM_BLOCK_LEN, - METRIC_BLOCK_LEN_MMV1, - INSTANCE_BLOCK_LEN_MMV1, - METRIC_BLOCK_LEN_MMV2, - INSTANCE_BLOCK_LEN_MMV2, + Endian, CLUSTER_ID_BIT_LEN, HDR_LEN, INDOM_BLOCK_LEN, INSTANCE_BLOCK_LEN_MMV1, + INSTANCE_BLOCK_LEN_MMV2, METRIC_BLOCK_LEN_MMV1, METRIC_BLOCK_LEN_MMV2, STRING_BLOCK_LEN, + TOC_BLOCK_LEN, VALUE_BLOCK_LEN, }; pub mod metric; @@ -60,21 +52,20 @@ fn osstr_from_bytes(slice: &[u8]) -> &OsStr { fn get_pcp_root() -> PathBuf { match env::var_os("PCP_DIR") { Some(val) => PathBuf::from(val), - None => PathBuf::from(MAIN_SEPARATOR.to_string()) + None => PathBuf::from(MAIN_SEPARATOR.to_string()), } } fn init_pcp_conf(pcp_root: &Path) -> io::Result<()> { /* attempt to load variables from pcp_root/etc/pcp.conf into environment. - if pcp_root/etc/pcp.conf is not a file, can't be read, or parsing it - fails, we *don't* return the error */ + if pcp_root/etc/pcp.conf is not a file, can't be read, or parsing it + fails, we *don't* return the error */ parse_pcp_conf(pcp_root.join("etc").join("pcp.conf")).ok(); /* attempt to load variables from pcp_root/$PCP_CONF into environment. - if pcp_root/$PCP_CONF is not a file, can't be read, or parsing it - fails, we *do* return the error */ - let pcp_conf = pcp_root - .join(env::var_os("PCP_CONF").unwrap_or(OsString::new())); + if pcp_root/$PCP_CONF is not a file, can't be read, or parsing it + fails, we *do* return the error */ + let pcp_conf = pcp_root.join(env::var_os("PCP_CONF").unwrap_or(OsString::new())); parse_pcp_conf(pcp_conf) } @@ -83,7 +74,7 @@ fn parse_pcp_conf>(conf_path: P) -> io::Result<()> { let mut buf_reader = BufReader::new(pcp_conf); /* According to man 5 pcp.conf, syntax rules for pcp.conf are - 1. general syntax is PCP_VARIABLE_NAME=value to end of line + 1. general syntax is PCP_VARIABLE_NAME=value to end of line 2. blank lines and lines begining with # are ignored 3. variable names that aren't prefixed with PCP_ are silently ignored 4. there should be no space between the variable name and the literal = @@ -91,22 +82,19 @@ fn parse_pcp_conf>(conf_path: P) -> io::Result<()> { */ lazy_static! { static ref RE: Regex = - Regex::new("(?-u)^(PCP_[[:alnum:]_]+)=([^\"\'].*[^\"\'])\n$") - .unwrap(); + Regex::new("(?-u)^(PCP_[[:alnum:]_]+)=([^\"\'].*[^\"\'])\n$").unwrap(); } let mut line = Vec::new(); while buf_reader.read_until(b'\n', &mut line)? > 0 { match RE.captures(&line) { - Some(caps) => { - match (caps.get(1), caps.get(2)) { - (Some(key), Some(val)) => env::set_var( - osstr_from_bytes(key.as_bytes()), - osstr_from_bytes(val.as_bytes()), - ), - _ => {} - } - } + Some(caps) => match (caps.get(1), caps.get(2)) { + (Some(key), Some(val)) => env::set_var( + osstr_from_bytes(key.as_bytes()), + osstr_from_bytes(val.as_bytes()), + ), + _ => {} + }, _ => {} } line.clear(); @@ -122,12 +110,11 @@ fn get_mmv_dir() -> io::Result { mmv_dir.push(match env::var_os(PCP_TMP_DIR_KEY) { Some(val) => PathBuf::from(val), None => { - init_pcp_conf(&pcp_root).ok(); /* re-check if PCP_TMP_DIR is set after parsing (any) conf files - if not, default to OS-specific temp dir and set PCP_TMP_DIR - so we don't enter this block again */ + if not, default to OS-specific temp dir and set PCP_TMP_DIR + so we don't enter this block again */ match env::var_os(PCP_TMP_DIR_KEY) { Some(val) => PathBuf::from(val), None => { @@ -161,12 +148,12 @@ impl fmt::Display for MMVFlags { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut prev_flag = false; - if self.contains(NOPREFIX) { + if self.contains(NOPREFIX) { write!(f, "no prefix")?; prev_flag = true; } - if self.contains(PROCESS) { + if self.contains(PROCESS) { if prev_flag { write!(f, ",")?; } @@ -174,7 +161,7 @@ impl fmt::Display for MMVFlags { prev_flag = true; } - if self.contains(SENTINEL) { + if self.contains(SENTINEL) { if prev_flag { write!(f, ",")?; } @@ -194,7 +181,7 @@ impl fmt::Display for MMVFlags { pub struct Client { flags: MMVFlags, cluster_id: u32, - mmv_path: PathBuf + mmv_path: PathBuf, } impl Client { @@ -207,18 +194,17 @@ impl Client { /// /// Note that only the 12 least significant bits of `cluster_id` will be /// used. - pub fn new_custom(name: &str, flags: MMVFlags, cluster_id: u32) - -> io::Result { + pub fn new_custom(name: &str, flags: MMVFlags, cluster_id: u32) -> io::Result { let mmv_path = get_mmv_dir()?.join(name); let cluster_id = cluster_id & ((1 << CLUSTER_ID_BIT_LEN) - 1); Ok(Client { flags: flags, cluster_id: cluster_id, - mmv_path: mmv_path + mmv_path: mmv_path, }) } - + /// Exports metrics to an MMV file at `mmv_path` /// /// If an MMV file is already present at `mmv_path`, it's overwritten @@ -254,7 +240,7 @@ impl Client { MMV layout: -- MMV Header - + -- Instance Domain TOC Block -- Instances TOC Block -- Metrics TOC Block @@ -266,7 +252,7 @@ impl Client { -- Metrics section -- Values section -- Strings section - + After writing, every metric is given ownership of the respective memory-mapped slice that contains the metric's value. This is to ensure that the metric @@ -274,32 +260,21 @@ impl Client { it's value. */ - let hdr_toc_len = HDR_LEN + TOC_BLOCK_LEN*ws.n_toc; + let hdr_toc_len = HDR_LEN + TOC_BLOCK_LEN * ws.n_toc; ws.indom_sec_off = hdr_toc_len; - ws.instance_sec_off = - ws.indom_sec_off - + INDOM_BLOCK_LEN*ws.n_indoms; - + ws.instance_sec_off = ws.indom_sec_off + INDOM_BLOCK_LEN * ws.n_indoms; + let (instance_blk_len, metric_blk_len) = match mmv_ver { Version::V1 => (INSTANCE_BLOCK_LEN_MMV1, METRIC_BLOCK_LEN_MMV1), - Version::V2 => (INSTANCE_BLOCK_LEN_MMV2, METRIC_BLOCK_LEN_MMV2) + Version::V2 => (INSTANCE_BLOCK_LEN_MMV2, METRIC_BLOCK_LEN_MMV2), }; - ws.metric_sec_off = - ws.instance_sec_off - + instance_blk_len*ws.n_instances; - ws.value_sec_off = - ws.metric_sec_off - + metric_blk_len*ws.n_metrics; - ws.string_sec_off = - ws.value_sec_off - + VALUE_BLOCK_LEN*ws.n_values; - - let mmv_size = ( - ws.string_sec_off - + STRING_BLOCK_LEN*ws.n_strings - ) as usize; + ws.metric_sec_off = ws.instance_sec_off + instance_blk_len * ws.n_instances; + ws.value_sec_off = ws.metric_sec_off + metric_blk_len * ws.n_metrics; + ws.string_sec_off = ws.value_sec_off + VALUE_BLOCK_LEN * ws.n_values; + + let mmv_size = (ws.string_sec_off + STRING_BLOCK_LEN * ws.n_strings) as usize; let mut file = OpenOptions::new() .read(true) @@ -310,9 +285,7 @@ impl Client { file.write(&vec![0; mmv_size])?; - ws.mmap_view = Some( - Mmap::open(&file, Protection::ReadWrite)?.into_view_sync() - ); + ws.mmap_view = Some(Mmap::open(&file, Protection::ReadWrite)?.into_view_sync()); let mut mmap_view = unsafe { ws.mmap_view.as_mut().unwrap().clone() }; let mut c = Cursor::new(unsafe { mmap_view.as_mut_slice() }); @@ -334,7 +307,7 @@ impl Client { // unlock header; has to be done last c.set_position(ws.gen2_off); c.write_i64::(ws.gen)?; - + Ok(()) } @@ -349,14 +322,18 @@ impl Client { } } -fn write_mmv_header(ws: &mut MMVWriterState, c: &mut Cursor<&mut [u8]>, mmv_ver: Version) -> io::Result<()> { +fn write_mmv_header( + ws: &mut MMVWriterState, + c: &mut Cursor<&mut [u8]>, + mmv_ver: Version, +) -> io::Result<()> { // MMV\0 c.write_all(b"MMV\0")?; // version match mmv_ver { Version::V1 => c.write_u32::(1)?, - Version::V2 => c.write_u32::(2)? + Version::V2 => c.write_u32::(2)?, } // generation1 @@ -375,7 +352,12 @@ fn write_mmv_header(ws: &mut MMVWriterState, c: &mut Cursor<&mut [u8]>, mmv_ver: c.write_u32::(ws.cluster_id) } -fn write_toc_block(sec: u32, entries: u32, sec_off: u64, c: &mut Cursor<&mut [u8]>) -> io::Result<()> { +fn write_toc_block( + sec: u32, + entries: u32, + sec_off: u64, + c: &mut Cursor<&mut [u8]>, +) -> io::Result<()> { if entries > 0 { // section type c.write_u32::(sec)?; @@ -395,18 +377,15 @@ fn test_mmv_header() { let cluster_id = thread_rng().gen::(); let flags = PROCESS | SENTINEL; let client = Client::new_custom("mmv_header_test", flags, cluster_id).unwrap(); - - client.export(&mut[]).unwrap(); + + client.export(&mut []).unwrap(); let mut file = File::open(client.mmv_path()).unwrap(); let mut header = Vec::new(); - assert!( - HDR_LEN as usize - <= file.read_to_end(&mut header).unwrap() - ); - + assert!(HDR_LEN as usize <= file.read_to_end(&mut header).unwrap()); + let mut cursor = Cursor::new(header); - + // test "MMV\0" assert_eq!('M' as u8, cursor.read_u8().unwrap()); assert_eq!('M' as u8, cursor.read_u8().unwrap()); @@ -433,10 +412,8 @@ fn test_mmv_header() { fn test_mmv_dir() { let pcp_root = get_pcp_root(); let mmv_dir = get_mmv_dir().unwrap(); - let tmp_dir = PathBuf::from( - env::var_os(PCP_TMP_DIR_KEY) - .expect(&format!("{} not set", PCP_TMP_DIR_KEY)) - ); + let tmp_dir = + PathBuf::from(env::var_os(PCP_TMP_DIR_KEY).expect(&format!("{} not set", PCP_TMP_DIR_KEY))); assert!(mmv_dir.is_dir()); assert_eq!(mmv_dir, pcp_root.join(tmp_dir).join(MMV_DIR_SUFFIX)); @@ -444,7 +421,7 @@ fn test_mmv_dir() { #[test] fn test_init_pcp_conf() { - let conf_keys = vec!( + let conf_keys = vec![ "PCP_VERSION", "PCP_USER", "PCP_GROUP", @@ -478,7 +455,7 @@ fn test_init_pcp_conf() { "PCP_TMPFILE_DIR", "PCP_DOC_DIR", "PCP_DEMOS_DIR", - ); + ]; let pcp_root = get_pcp_root(); if init_pcp_conf(&pcp_root).is_ok() { diff --git a/src/lib.rs b/src/lib.rs index 7126a62..24d3c31 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,11 +3,16 @@ extern crate hdrsample; extern crate memmap; extern crate regex; extern crate time; -#[macro_use] extern crate bitflags; -#[macro_use] extern crate lazy_static; -#[cfg(test)] extern crate rand; -#[cfg(unix)] extern crate nix; -#[cfg(windows)] extern crate kernel32; +#[macro_use] +extern crate bitflags; +#[macro_use] +extern crate lazy_static; +#[cfg(windows)] +extern crate kernel32; +#[cfg(unix)] +extern crate nix; +#[cfg(test)] +extern crate rand; const CLUSTER_ID_BIT_LEN: usize = 12; const ITEM_BIT_LEN: usize = 10; diff --git a/src/mmv/mmvfmt.rs b/src/mmv/mmvfmt.rs index e483e73..3fc6d91 100644 --- a/src/mmv/mmvfmt.rs +++ b/src/mmv/mmvfmt.rs @@ -1,6 +1,6 @@ -use super::*; -use super::super::client::MMVFlags; use super::super::client::metric::{Semantics, Unit}; +use super::super::client::MMVFlags; +use super::*; use std::mem; impl fmt::Display for Header { @@ -10,30 +10,45 @@ impl fmt::Display for Header { writeln!(f, "TOC count = {}", self.toc_count())?; writeln!(f, "Cluster = {}", self.cluster_id())?; writeln!(f, "Process = {}", self.pid())?; - writeln!(f, "Flags = {}", MMVFlags::from_bits_truncate(self.flags())) + writeln!( + f, + "Flags = {}", + MMVFlags::from_bits_truncate(self.flags()) + ) } } fn write_indoms(f: &mut fmt::Formatter, indom_toc: &TocBlk, mmv: &MMV) -> fmt::Result { - writeln!(f, "TOC[{}]: toc offset {}, indoms offset {} ({} entries)", - indom_toc._toc_index(), indom_toc._mmv_offset(), indom_toc.sec_offset(), indom_toc.entries())?; + writeln!( + f, + "TOC[{}]: toc offset {}, indoms offset {} ({} entries)", + indom_toc._toc_index(), + indom_toc._mmv_offset(), + indom_toc.sec_offset(), + indom_toc.entries() + )?; for (offset, indom) in mmv.indom_blks() { if let Some(ref indom_id) = *indom.indom() { - write!(f, " [{}/{}] {} instances, starting at offset ", - indom_id, offset, indom.instances())?; + write!( + f, + " [{}/{}] {} instances, starting at offset ", + indom_id, + offset, + indom.instances() + )?; match *indom.instances_offset() { Some(ref instances_offset) => writeln!(f, "{}", instances_offset)?, - None => writeln!(f, "(no instances)")? + None => writeln!(f, "(no instances)")?, } - + write!(f, " ")?; match *indom.short_help_offset() { Some(ref short_help_offset) => { let shortext = mmv.string_blks().get(short_help_offset).unwrap().string(); writeln!(f, "shorttext={}", shortext)?; } - None => writeln!(f, "(no shorttext)")? + None => writeln!(f, "(no shorttext)")?, } write!(f, " ")?; @@ -42,7 +57,7 @@ fn write_indoms(f: &mut fmt::Formatter, indom_toc: &TocBlk, mmv: &MMV) -> fmt::R let longtext = mmv.string_blks().get(long_help_offset).unwrap().string(); writeln!(f, "longtext={}", longtext)? } - None => writeln!(f, "(no longtext)")? + None => writeln!(f, "(no longtext)")?, } } } @@ -51,7 +66,11 @@ fn write_indoms(f: &mut fmt::Formatter, indom_toc: &TocBlk, mmv: &MMV) -> fmt::R } // note: doesn't write newline at the end -fn write_version_specific_string(f: &mut fmt::Formatter, string: &VersionSpecificString, mmv: &MMV) -> fmt::Result { +fn write_version_specific_string( + f: &mut fmt::Formatter, + string: &VersionSpecificString, + mmv: &MMV, +) -> fmt::Result { match string { &VersionSpecificString::String(ref string) => write!(f, "{}", string), &VersionSpecificString::Offset(ref offset) => { @@ -62,8 +81,14 @@ fn write_version_specific_string(f: &mut fmt::Formatter, string: &VersionSpecifi } fn write_instances(f: &mut fmt::Formatter, instance_toc: &TocBlk, mmv: &MMV) -> fmt::Result { - writeln!(f, "TOC[{}]: toc offset {}, instances offset {} ({} entries)", - instance_toc._toc_index(), instance_toc._mmv_offset(), instance_toc.sec_offset(), instance_toc.entries())?; + writeln!( + f, + "TOC[{}]: toc offset {}, instances offset {} ({} entries)", + instance_toc._toc_index(), + instance_toc._mmv_offset(), + instance_toc.sec_offset(), + instance_toc.entries() + )?; for (offset, instance) in mmv.instance_blks() { write!(f, " ")?; @@ -72,12 +97,17 @@ fn write_instances(f: &mut fmt::Formatter, instance_toc: &TocBlk, mmv: &MMV) -> let indom = mmv.indom_blks().get(indom_offset).unwrap(); match *indom.indom() { Some(ref indom_id) => write!(f, "[{}", indom_id)?, - None => write!(f, "[(no indom)")? + None => write!(f, "[(no indom)")?, } - }, - None => write!(f, "[(no indom)")? + } + None => write!(f, "[(no indom)")?, } - write!(f, "/{}] instance = [{} or \"", offset, instance.internal_id())?; + write!( + f, + "/{}] instance = [{} or \"", + offset, + instance.internal_id() + )?; write_version_specific_string(f, instance.external_id(), mmv)?; writeln!(f, "\"]")?; } @@ -86,8 +116,14 @@ fn write_instances(f: &mut fmt::Formatter, instance_toc: &TocBlk, mmv: &MMV) -> } fn write_metrics(f: &mut fmt::Formatter, metric_toc: &TocBlk, mmv: &MMV) -> fmt::Result { - writeln!(f, "TOC[{}]: toc offset {}, metrics offset {} ({} entries)", - metric_toc._toc_index(), metric_toc._mmv_offset(), metric_toc.sec_offset(), metric_toc.entries())?; + writeln!( + f, + "TOC[{}]: toc offset {}, metrics offset {} ({} entries)", + metric_toc._toc_index(), + metric_toc._mmv_offset(), + metric_toc.sec_offset(), + metric_toc.entries() + )?; for (offset, metric) in mmv.metric_blks() { if let Some(item) = *metric.item() { @@ -98,22 +134,22 @@ fn write_metrics(f: &mut fmt::Formatter, metric_toc: &TocBlk, mmv: &MMV) -> fmt: write!(f, " ")?; match MTCode::from_u32(metric.typ()) { Some(mtcode) => write!(f, "type={}", mtcode)?, - None => write!(f, "(invalid type)")? + None => write!(f, "(invalid type)")?, } write!(f, ", ")?; match Semantics::from_u32(metric.sem()) { Some(sem) => write!(f, "sem={}", sem)?, - None => write!(f, "(invalid semantics)")? + None => write!(f, "(invalid semantics)")?, } write!(f, ", ")?; writeln!(f, "pad=0x{:x}", metric.pad())?; - + writeln!(f, " unit={}", Unit::from_raw(metric.unit()))?; write!(f, " ")?; match *metric.indom() { Some(indom) => writeln!(f, "indom={}", indom)?, - None => writeln!(f, "(no indom)")? + None => writeln!(f, "(no indom)")?, } write!(f, " ")?; @@ -122,7 +158,7 @@ fn write_metrics(f: &mut fmt::Formatter, metric_toc: &TocBlk, mmv: &MMV) -> fmt: let shortext = mmv.string_blks().get(short_help_offset).unwrap().string(); writeln!(f, "shorttext={}", shortext)?; } - None => writeln!(f, "(no shorttext)")? + None => writeln!(f, "(no shorttext)")?, } write!(f, " ")?; @@ -131,7 +167,7 @@ fn write_metrics(f: &mut fmt::Formatter, metric_toc: &TocBlk, mmv: &MMV) -> fmt: let longtext = mmv.string_blks().get(long_help_offset).unwrap().string(); writeln!(f, "longtext={}", longtext)?; } - None => writeln!(f, "(no longtext)")? + None => writeln!(f, "(no longtext)")?, } } } @@ -140,8 +176,14 @@ fn write_metrics(f: &mut fmt::Formatter, metric_toc: &TocBlk, mmv: &MMV) -> fmt: } fn write_values(f: &mut fmt::Formatter, value_toc: &TocBlk, mmv: &MMV) -> fmt::Result { - writeln!(f, "TOC[{}]: toc offset {}, values offset {} ({} entries)", - value_toc._toc_index(), value_toc._mmv_offset(), value_toc.sec_offset(), value_toc.entries())?; + writeln!( + f, + "TOC[{}]: toc offset {}, values offset {} ({} entries)", + value_toc._toc_index(), + value_toc._mmv_offset(), + value_toc.sec_offset(), + value_toc.entries() + )?; for (offset, value) in mmv.value_blks() { if let Some(ref metric_offset) = *value.metric_offset() { @@ -163,30 +205,23 @@ fn write_values(f: &mut fmt::Formatter, value_toc: &TocBlk, mmv: &MMV) -> fmt::R let string = mmv.string_blks().get(string_offset).unwrap(); writeln!(f, "\"{}\"", string.string())?; } - None => { - match MTCode::from_u32(metric.typ()) { - Some(mtcode) => { - match mtcode { - MTCode::U64 | MTCode::U32 => writeln!(f, "{}", value.value())?, - MTCode::I64 => writeln!(f, "{}", value.value() as i64)?, - MTCode::I32 => writeln!(f, "{}", value.value() as i32)?, - MTCode::F32 => { - let float = unsafe { - mem::transmute::(value.value() as u32) - }; - writeln!(f, "{}", float)? - }, - MTCode::F64 => { - let double = unsafe { - mem::transmute::(value.value()) - }; - writeln!(f, "{}", double)? - }, - MTCode::String => writeln!(f, "(no string offset)")?, - } - }, - None => writeln!(f, "{}", value.value())? - } + None => match MTCode::from_u32(metric.typ()) { + Some(mtcode) => match mtcode { + MTCode::U64 | MTCode::U32 => writeln!(f, "{}", value.value())?, + MTCode::I64 => writeln!(f, "{}", value.value() as i64)?, + MTCode::I32 => writeln!(f, "{}", value.value() as i32)?, + MTCode::F32 => { + let float = + unsafe { mem::transmute::(value.value() as u32) }; + writeln!(f, "{}", float)? + } + MTCode::F64 => { + let double = unsafe { mem::transmute::(value.value()) }; + writeln!(f, "{}", double)? + } + MTCode::String => writeln!(f, "(no string offset)")?, + }, + None => writeln!(f, "{}", value.value())?, }, } } @@ -197,11 +232,17 @@ fn write_values(f: &mut fmt::Formatter, value_toc: &TocBlk, mmv: &MMV) -> fmt::R } fn write_strings(f: &mut fmt::Formatter, string_toc: &TocBlk, mmv: &MMV) -> fmt::Result { - writeln!(f, "TOC[{}]: toc offset {}, strings offset {} ({} entries)", - string_toc._toc_index(), string_toc._mmv_offset(), string_toc.sec_offset(), string_toc.entries())?; + writeln!( + f, + "TOC[{}]: toc offset {}, strings offset {} ({} entries)", + string_toc._toc_index(), + string_toc._mmv_offset(), + string_toc.sec_offset(), + string_toc.entries() + )?; for (i, (offset, string)) in mmv.string_blks().iter().enumerate() { - writeln!(f, " [{}/{}] {}", i+1, offset, string.string())?; + writeln!(f, " [{}/{}] {}", i + 1, offset, string.string())?; } Ok(()) diff --git a/src/mmv/mod.rs b/src/mmv/mod.rs index e48ddb7..7a68000 100644 --- a/src/mmv/mod.rs +++ b/src/mmv/mod.rs @@ -4,8 +4,8 @@ use std::ffi::CStr; // Used to read null-terminated strings in MMV files use std::fmt; use std::fs::File; use std::io; -use std::io::Cursor; use std::io::prelude::*; +use std::io::Cursor; use std::path::Path; use std::str; @@ -36,7 +36,7 @@ pub enum MTCode { /// 64-bit double F64, /// String - String + String, } impl MTCode { @@ -49,7 +49,7 @@ impl MTCode { 4 => Some(MTCode::F32), 5 => Some(MTCode::F64), 6 => Some(MTCode::String), - _ => None + _ => None, } } } @@ -63,19 +63,14 @@ impl fmt::Display for MTCode { MTCode::U64 => write!(f, "Uint64")?, MTCode::F32 => write!(f, "Float32")?, MTCode::F64 => write!(f, "Double64")?, - MTCode::String => write!(f, "String")? + MTCode::String => write!(f, "String")?, } write!(f, " (0x{:x})", *self as u32) } } use super::{ - Endian, - MMV1_NAME_MAX_LEN, - STRING_BLOCK_LEN, - CLUSTER_ID_BIT_LEN, - ITEM_BIT_LEN, - INDOM_BIT_LEN + Endian, CLUSTER_ID_BIT_LEN, INDOM_BIT_LEN, ITEM_BIT_LEN, MMV1_NAME_MAX_LEN, STRING_BLOCK_LEN, }; fn is_valid_indom(indom: u32) -> bool { @@ -102,7 +97,7 @@ pub enum MMVDumpError { /// IO error while reading MMV Io(io::Error), /// UTF-8 error while parsing MMV strings - Utf8(str::Utf8Error) + Utf8(str::Utf8Error), } impl From for MMVDumpError { @@ -140,21 +135,43 @@ pub struct MMV { value_blks: BTreeMap, string_blks: BTreeMap, indom_blks: BTreeMap, - instance_blks: BTreeMap + instance_blks: BTreeMap, } impl MMV { - pub fn header(&self) -> &Header { &self.header } - pub fn metric_toc(&self) -> &TocBlk { &self.metric_toc } - pub fn value_toc(&self) -> &TocBlk { &self.value_toc } - pub fn string_toc(&self) -> &Option { &self.string_toc } - pub fn indom_toc(&self) -> &Option { &self.indom_toc } - pub fn instance_toc(&self) -> &Option { &self.instance_toc } - pub fn metric_blks(&self) -> &BTreeMap { &self.metric_blks } - pub fn value_blks(&self) -> &BTreeMap { &self.value_blks } - pub fn string_blks(&self) -> &BTreeMap { &self.string_blks } - pub fn indom_blks(&self) -> &BTreeMap { &self.indom_blks } - pub fn instance_blks(&self) -> &BTreeMap { &self.instance_blks } + pub fn header(&self) -> &Header { + &self.header + } + pub fn metric_toc(&self) -> &TocBlk { + &self.metric_toc + } + pub fn value_toc(&self) -> &TocBlk { + &self.value_toc + } + pub fn string_toc(&self) -> &Option { + &self.string_toc + } + pub fn indom_toc(&self) -> &Option { + &self.indom_toc + } + pub fn instance_toc(&self) -> &Option { + &self.instance_toc + } + pub fn metric_blks(&self) -> &BTreeMap { + &self.metric_blks + } + pub fn value_blks(&self) -> &BTreeMap { + &self.value_blks + } + pub fn string_blks(&self) -> &BTreeMap { + &self.string_blks + } + pub fn indom_blks(&self) -> &BTreeMap { + &self.indom_blks + } + pub fn instance_blks(&self) -> &BTreeMap { + &self.instance_blks + } } #[derive(Copy, Clone)] @@ -163,7 +180,7 @@ pub enum Version { /// Version 1 V1 = 1, /// Version 2 - V2 = 2 + V2 = 2, } impl Version { @@ -171,7 +188,7 @@ impl Version { match x { 1 => Some(Version::V1), 2 => Some(Version::V2), - _ => None + _ => None, } } } @@ -192,14 +209,30 @@ pub struct Header { } impl Header { - pub fn magic(&self) -> &[u8; 4] { &self.magic } - pub fn version(&self) -> Version { self.version } - pub fn gen1(&self) -> i64 { self.gen1 } - pub fn gen2(&self) -> i64 { self.gen2 } - pub fn toc_count(&self) -> u32 { self.toc_count } - pub fn flags(&self) -> u32 { self.flags } - pub fn pid(&self) -> i32 { self.pid } - pub fn cluster_id(&self) -> u32 { self.cluster_id } + pub fn magic(&self) -> &[u8; 4] { + &self.magic + } + pub fn version(&self) -> Version { + self.version + } + pub fn gen1(&self) -> i64 { + self.gen1 + } + pub fn gen2(&self) -> i64 { + self.gen2 + } + pub fn toc_count(&self) -> u32 { + self.toc_count + } + pub fn flags(&self) -> u32 { + self.flags + } + pub fn pid(&self) -> i32 { + self.pid + } + pub fn cluster_id(&self) -> u32 { + self.cluster_id + } } impl Header { @@ -225,7 +258,7 @@ impl Header { let gen2 = r.read_i64::()?; if gen1 != gen2 { return_mmvdumperror!("Generation timestamps don't match", 0); - } + } let toc_count = r.read_u32::()?; if toc_count > 5 || toc_count < 2 { @@ -248,7 +281,7 @@ impl Header { toc_count: toc_count, flags: flags, pid: pid, - cluster_id: cluster_id + cluster_id: cluster_id, }) } } @@ -262,15 +295,25 @@ pub struct TocBlk { _mmv_offset: u64, sec: u32, entries: u32, - sec_offset: u64 + sec_offset: u64, } impl TocBlk { - pub fn _toc_index(&self) -> u32 { self._toc_index } - pub fn _mmv_offset(&self) -> u64 { self._mmv_offset } - pub fn sec(&self) -> u32 { self.sec } - pub fn entries(&self) -> u32 { self.entries } - pub fn sec_offset(&self) -> u64 { self.sec_offset } + pub fn _toc_index(&self) -> u32 { + self._toc_index + } + pub fn _mmv_offset(&self) -> u64 { + self._mmv_offset + } + pub fn sec(&self) -> u32 { + self.sec + } + pub fn entries(&self) -> u32 { + self.entries + } + pub fn sec_offset(&self) -> u64 { + self.sec_offset + } } impl TocBlk { @@ -292,7 +335,7 @@ impl TocBlk { _mmv_offset: 0, sec: sec, entries: entries, - sec_offset: sec_offset + sec_offset: sec_offset, }) } } @@ -302,7 +345,7 @@ pub enum VersionSpecificString { /// MMV version 1 direct string String(String), /// MMV version 2 offset to string block - Offset(u64) + Offset(u64), } /// Metric block structure @@ -318,19 +361,37 @@ pub struct MetricBlk { indom: Option, pad: u32, short_help_offset: Option, - long_help_offset: Option + long_help_offset: Option, } impl MetricBlk { - pub fn name(&self) -> &VersionSpecificString { &self.name } - pub fn item(&self) -> &Option { &self.item } - pub fn typ(&self) -> u32 { self.typ } - pub fn sem(&self) -> u32 { self.sem } - pub fn unit(&self) -> u32 { self.unit } - pub fn indom(&self) -> &Option { &self.indom } - pub fn pad(&self) -> u32 { self.pad } - pub fn short_help_offset(&self) -> &Option { &self.short_help_offset } - pub fn long_help_offset(&self) -> &Option { &self.long_help_offset } + pub fn name(&self) -> &VersionSpecificString { + &self.name + } + pub fn item(&self) -> &Option { + &self.item + } + pub fn typ(&self) -> u32 { + self.typ + } + pub fn sem(&self) -> u32 { + self.sem + } + pub fn unit(&self) -> u32 { + self.unit + } + pub fn indom(&self) -> &Option { + &self.indom + } + pub fn pad(&self) -> u32 { + self.pad + } + pub fn short_help_offset(&self) -> &Option { + &self.short_help_offset + } + pub fn long_help_offset(&self) -> &Option { + &self.long_help_offset + } } impl MetricBlk { @@ -339,14 +400,10 @@ impl MetricBlk { Version::V1 => { let mut name_bytes = [0; MMV1_NAME_MAX_LEN as usize]; r.read_exact(&mut name_bytes)?; - let cstr = unsafe { - CStr::from_ptr(name_bytes.as_ptr() as *const i8) - }; + let cstr = unsafe { CStr::from_ptr(name_bytes.as_ptr() as *const i8) }; VersionSpecificString::String(cstr.to_str()?.to_owned()) - }, - Version::V2 => { - VersionSpecificString::Offset(r.read_u64::()?) } + Version::V2 => VersionSpecificString::Offset(r.read_u64::()?), }; let item = r.read_u32::()?; @@ -362,29 +419,41 @@ impl MetricBlk { let short_help_offset = r.read_u64::()?; let long_help_offset = r.read_u64::()?; - + Ok(MetricBlk { name: name, item: { - if is_valid_item(item) { Some(item) } - else { None } + if is_valid_item(item) { + Some(item) + } else { + None + } }, typ: typ, sem: sem, unit: unit, indom: { - if is_valid_indom(indom) { Some(indom) } - else { None } + if is_valid_indom(indom) { + Some(indom) + } else { + None + } }, pad: pad, short_help_offset: { - if is_valid_blk_offset(short_help_offset) { Some(short_help_offset) } - else { None } + if is_valid_blk_offset(short_help_offset) { + Some(short_help_offset) + } else { + None + } }, long_help_offset: { - if is_valid_blk_offset(long_help_offset) { Some(long_help_offset) } - else { None } - } + if is_valid_blk_offset(long_help_offset) { + Some(long_help_offset) + } else { + None + } + }, }) } } @@ -397,14 +466,22 @@ pub struct ValueBlk { value: u64, string_offset: Option, metric_offset: Option, - instance_offset: Option + instance_offset: Option, } impl ValueBlk { - pub fn value(&self) -> u64 { self.value } - pub fn string_offset(&self) -> &Option { &self.string_offset } - pub fn metric_offset(&self) -> &Option { &self.metric_offset } - pub fn instance_offset(&self) -> &Option { &self.instance_offset } + pub fn value(&self) -> u64 { + self.value + } + pub fn string_offset(&self) -> &Option { + &self.string_offset + } + pub fn metric_offset(&self) -> &Option { + &self.metric_offset + } + pub fn instance_offset(&self) -> &Option { + &self.instance_offset + } } impl ValueBlk { @@ -417,16 +494,25 @@ impl ValueBlk { Ok(ValueBlk { value: value, string_offset: { - if is_valid_blk_offset(string_offset) { Some(string_offset) } - else { None } + if is_valid_blk_offset(string_offset) { + Some(string_offset) + } else { + None + } }, metric_offset: { - if is_valid_blk_offset(metric_offset) { Some(metric_offset) } - else { None } + if is_valid_blk_offset(metric_offset) { + Some(metric_offset) + } else { + None + } }, instance_offset: { - if is_valid_blk_offset(instance_offset) { Some(instance_offset) } - else { None } + if is_valid_blk_offset(instance_offset) { + Some(instance_offset) + } else { + None + } }, }) } @@ -441,15 +527,25 @@ pub struct IndomBlk { instances: u32, instances_offset: Option, short_help_offset: Option, - long_help_offset: Option + long_help_offset: Option, } impl IndomBlk { - pub fn indom(&self) -> &Option { &self.indom } - pub fn instances(&self) -> u32 { self.instances } - pub fn instances_offset(&self) -> &Option { &self.instances_offset } - pub fn short_help_offset(&self) -> &Option { &self.short_help_offset } - pub fn long_help_offset(&self) -> &Option { &self.long_help_offset } + pub fn indom(&self) -> &Option { + &self.indom + } + pub fn instances(&self) -> u32 { + self.instances + } + pub fn instances_offset(&self) -> &Option { + &self.instances_offset + } + pub fn short_help_offset(&self) -> &Option { + &self.short_help_offset + } + pub fn long_help_offset(&self) -> &Option { + &self.long_help_offset + } } impl IndomBlk { @@ -462,22 +558,34 @@ impl IndomBlk { Ok(IndomBlk { indom: { - if is_valid_indom(indom) { Some(indom) } - else { None } + if is_valid_indom(indom) { + Some(indom) + } else { + None + } }, instances: instances, instances_offset: { - if is_valid_blk_offset(instances_offset) { Some(instances_offset) } - else { None } + if is_valid_blk_offset(instances_offset) { + Some(instances_offset) + } else { + None + } }, short_help_offset: { - if is_valid_blk_offset(short_help_offset) { Some(short_help_offset) } - else { None } + if is_valid_blk_offset(short_help_offset) { + Some(short_help_offset) + } else { + None + } }, long_help_offset: { - if is_valid_blk_offset(long_help_offset) { Some(long_help_offset) } - else { None } - } + if is_valid_blk_offset(long_help_offset) { + Some(long_help_offset) + } else { + None + } + }, }) } } @@ -490,14 +598,22 @@ pub struct InstanceBlk { indom_offset: Option, pad: u32, internal_id: i32, - external_id: VersionSpecificString + external_id: VersionSpecificString, } impl InstanceBlk { - pub fn indom_offset(&self) -> &Option { &self.indom_offset } - pub fn pad(&self) -> u32 { self.pad } - pub fn internal_id(&self) -> i32 { self.internal_id } - pub fn external_id(&self) -> &VersionSpecificString { &self.external_id } + pub fn indom_offset(&self) -> &Option { + &self.indom_offset + } + pub fn pad(&self) -> u32 { + self.pad + } + pub fn internal_id(&self) -> i32 { + self.internal_id + } + pub fn external_id(&self) -> &VersionSpecificString { + &self.external_id + } } impl InstanceBlk { @@ -515,25 +631,23 @@ impl InstanceBlk { Version::V1 => { let mut external_id_bytes = [0; MMV1_NAME_MAX_LEN as usize]; r.read_exact(&mut external_id_bytes)?; - let cstr = unsafe { - CStr::from_ptr(external_id_bytes.as_ptr() as *const i8) - }; + let cstr = unsafe { CStr::from_ptr(external_id_bytes.as_ptr() as *const i8) }; VersionSpecificString::String(cstr.to_str()?.to_owned()) - }, - Version::V2 => { - VersionSpecificString::Offset(r.read_u64::()?) } + Version::V2 => VersionSpecificString::Offset(r.read_u64::()?), }; - Ok(InstanceBlk { indom_offset: { - if is_valid_blk_offset(indom_offset) { Some(indom_offset) } - else { None } + if is_valid_blk_offset(indom_offset) { + Some(indom_offset) + } else { + None + } }, pad: pad, internal_id: internal_id, - external_id: external_id + external_id: external_id, }) } } @@ -543,25 +657,23 @@ impl InstanceBlk { /// For reference to the C API, see /// https://github.com/performancecopilot/pcp/blob/master/src/include/pcp/mmv_dev.h#L60 pub struct StringBlk { - string: String + string: String, } impl StringBlk { - pub fn string(&self) -> &str { &self.string } + pub fn string(&self) -> &str { + &self.string + } } impl StringBlk { fn from_reader(r: &mut R) -> Result { let mut bytes = [0; STRING_BLOCK_LEN as usize]; r.read_exact(&mut bytes)?; - let cstr = unsafe { - CStr::from_ptr(bytes.as_ptr() as *const i8) - }; + let cstr = unsafe { CStr::from_ptr(bytes.as_ptr() as *const i8) }; let string = cstr.to_str()?.to_owned(); - Ok(StringBlk { - string: string - }) + Ok(StringBlk { string: string }) } } @@ -608,7 +720,7 @@ pub fn dump(mmv_path: &Path) -> Result { file.read_to_end(&mut mmv_bytes)?; let mut cursor = Cursor::new(mmv_bytes); - + let hdr = Header::from_reader(&mut cursor)?; let mut indom_toc = None; @@ -623,11 +735,17 @@ pub fn dump(mmv_path: &Path) -> Result { toc._toc_index = i; toc._mmv_offset = toc_position; - if toc.sec == INDOM_TOC_CODE { indom_toc = Some(toc); } - else if toc.sec == INSTANCE_TOC_CODE { instance_toc = Some(toc); } - else if toc.sec == METRIC_TOC_CODE { metric_toc = Some(toc); } - else if toc.sec == VALUES_TOC_CODE { value_toc = Some(toc); } - else if toc.sec == STRINGS_TOC_CODE { string_toc = Some(toc); } + if toc.sec == INDOM_TOC_CODE { + indom_toc = Some(toc); + } else if toc.sec == INSTANCE_TOC_CODE { + instance_toc = Some(toc); + } else if toc.sec == METRIC_TOC_CODE { + metric_toc = Some(toc); + } else if toc.sec == VALUES_TOC_CODE { + value_toc = Some(toc); + } else if toc.sec == STRINGS_TOC_CODE { + string_toc = Some(toc); + } } if metric_toc.is_none() { @@ -643,19 +761,17 @@ pub fn dump(mmv_path: &Path) -> Result { let value_blks = blks_from_toc!(value_toc, ValueBlk, cursor); let string_blks = blks_from_toc!(string_toc, StringBlk, cursor); - Ok( - MMV { - header: hdr, - metric_toc: metric_toc.unwrap(), - value_toc: value_toc.unwrap(), - string_toc: string_toc, - indom_toc: indom_toc, - instance_toc: instance_toc, - indom_blks: indom_blks, - instance_blks: instance_blks, - metric_blks: metric_blks, - value_blks: value_blks, - string_blks: string_blks - } - ) + Ok(MMV { + header: hdr, + metric_toc: metric_toc.unwrap(), + value_toc: value_toc.unwrap(), + string_toc: string_toc, + indom_toc: indom_toc, + instance_toc: instance_toc, + indom_blks: indom_blks, + instance_blks: instance_blks, + metric_blks: metric_blks, + value_blks: value_blks, + string_blks: string_blks, + }) } diff --git a/src/private.rs b/src/private.rs index a6078a4..a48dad0 100644 --- a/src/private.rs +++ b/src/private.rs @@ -16,7 +16,7 @@ macro_rules! private_decl { /// impossible to implement outside the crate. #[doc(hidden)] fn __rayon_private__(&self) -> ::private::PrivateMarker; - } + }; } macro_rules! private_impl { @@ -24,5 +24,5 @@ macro_rules! private_impl { fn __rayon_private__(&self) -> ::private::PrivateMarker { ::private::PrivateMarker } - } + }; } diff --git a/tests/mmvfmt.rs b/tests/mmvfmt.rs index e7230b8..285f965 100644 --- a/tests/mmvfmt.rs +++ b/tests/mmvfmt.rs @@ -17,12 +17,14 @@ fn test_mmvfmt() { let output_prefix = "mmvdump_op"; let output_suffix = ".golden"; - for i in 1..tests+1 { + for i in 1..tests + 1 { let mut output_path = testdata_dir.clone(); output_path.push(&format!("{}{}{}", output_prefix, i, output_suffix)); let mut golden_output = Vec::new(); - File::open(output_path).unwrap() - .read_to_end(&mut golden_output).unwrap(); + File::open(output_path) + .unwrap() + .read_to_end(&mut golden_output) + .unwrap(); let mut input_path = testdata_dir.clone(); input_path.push(&format!("{}{}{}", input_prefix, i, input_suffix));