From 56b5c28930799681205d15f60aa39f1fe288bbdb Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Wed, 27 Jul 2022 13:43:04 +0200 Subject: [PATCH] rrd: Entry type and clippy fixes Signed-off-by: Wolfgang Bumiller --- proxmox-rrd/examples/prrd.rs | 4 +- proxmox-rrd/src/cache.rs | 3 +- proxmox-rrd/src/cache/rrd_map.rs | 3 +- proxmox-rrd/src/lib.rs | 2 + proxmox-rrd/src/rrd.rs | 124 +++++++++++++++++++++++-------- 5 files changed, 104 insertions(+), 32 deletions(-) diff --git a/proxmox-rrd/examples/prrd.rs b/proxmox-rrd/examples/prrd.rs index 081cef98..5825f296 100644 --- a/proxmox-rrd/examples/prrd.rs +++ b/proxmox-rrd/examples/prrd.rs @@ -301,7 +301,9 @@ pub fn resize_rrd(path: String, rra_index: usize, slots: i64) -> Result<(), Erro let rra_end = rra.slot_end_time(rrd.source.last_update as u64); let rra_start = rra_end - rra.resolution * (rra.data.len() as u64); - let (start, reso, data) = rra.extract_data(rra_start, rra_end, rrd.source.last_update); + let (start, reso, data) = rra + .extract_data(rra_start, rra_end, rrd.source.last_update) + .into(); let mut new_rra = RRA::new(rra.cf, rra.resolution, new_slots as usize); new_rra.last_count = rra.last_count; diff --git a/proxmox-rrd/src/cache.rs b/proxmox-rrd/src/cache.rs index 90e4e470..1321e58d 100644 --- a/proxmox-rrd/src/cache.rs +++ b/proxmox-rrd/src/cache.rs @@ -13,6 +13,7 @@ use crossbeam_channel::{bounded, TryRecvError}; use proxmox_sys::fs::{create_path, CreateOptions}; use crate::rrd::{CF, DST, RRA, RRD}; +use crate::Entry; mod journal; use journal::*; @@ -217,7 +218,7 @@ impl RRDCache { resolution: u64, start: Option, end: Option, - ) -> Result>)>, Error> { + ) -> Result, Error> { self.rrd_map .read() .unwrap() diff --git a/proxmox-rrd/src/cache/rrd_map.rs b/proxmox-rrd/src/cache/rrd_map.rs index 56dde2e6..f907d350 100644 --- a/proxmox-rrd/src/cache/rrd_map.rs +++ b/proxmox-rrd/src/cache/rrd_map.rs @@ -9,6 +9,7 @@ use proxmox_sys::fs::create_path; use crate::rrd::{CF, DST, RRD}; use super::CacheConfig; +use crate::Entry; pub struct RRDMap { config: Arc, @@ -87,7 +88,7 @@ impl RRDMap { resolution: u64, start: Option, end: Option, - ) -> Result>)>, Error> { + ) -> Result, Error> { match self.map.get(&format!("{}/{}", base, name)) { Some(rrd) => Ok(Some(rrd.extract_data(cf, resolution, start, end)?)), None => Ok(None), diff --git a/proxmox-rrd/src/lib.rs b/proxmox-rrd/src/lib.rs index 2038170d..80b39438 100644 --- a/proxmox-rrd/src/lib.rs +++ b/proxmox-rrd/src/lib.rs @@ -9,6 +9,8 @@ mod rrd_v1; pub mod rrd; +#[doc(inline)] +pub use rrd::Entry; mod cache; pub use cache::*; diff --git a/proxmox-rrd/src/rrd.rs b/proxmox-rrd/src/rrd.rs index 4ae3ee93..6affa9a5 100644 --- a/proxmox-rrd/src/rrd.rs +++ b/proxmox-rrd/src/rrd.rs @@ -28,7 +28,7 @@ use crate::rrd_v1; pub const PROXMOX_RRD_MAGIC_2_0: [u8; 8] = [224, 200, 228, 27, 239, 112, 122, 159]; #[api()] -#[derive(Debug, Serialize, Deserialize, Copy, Clone, PartialEq)] +#[derive(Debug, Serialize, Deserialize, Copy, Clone, PartialEq, Eq)] #[serde(rename_all = "kebab-case")] /// RRD data source type pub enum DST { @@ -42,7 +42,7 @@ pub enum DST { } #[api()] -#[derive(Debug, Serialize, Deserialize, Copy, Clone, PartialEq)] +#[derive(Debug, Serialize, Deserialize, Copy, Clone, PartialEq, Eq)] #[serde(rename_all = "kebab-case")] /// Consolidation function pub enum CF { @@ -68,6 +68,42 @@ pub struct DataSource { pub last_value: f64, } +/// An RRD entry. +/// +/// Serializes as a tuple. +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde( + from = "(u64, u64, Vec>)", + into = "(u64, u64, Vec>)" +)] +pub struct Entry { + pub start: u64, + pub resolution: u64, + pub data: Vec>, +} + +impl Entry { + pub const fn new(start: u64, resolution: u64, data: Vec>) -> Self { + Self { + start, + resolution, + data, + } + } +} + +impl From for (u64, u64, Vec>) { + fn from(entry: Entry) -> (u64, u64, Vec>) { + (entry.start, entry.resolution, entry.data) + } +} + +impl From<(u64, u64, Vec>)> for Entry { + fn from(data: (u64, u64, Vec>)) -> Self { + Self::new(data.0, data.1, data.2) + } +} + impl DataSource { /// Create a new Instance pub fn new(dst: DST) -> Self { @@ -265,12 +301,7 @@ impl RRA { /// Extract data from `start` to `end`. The RRA itself does not /// store the `last_update` time, so you need to pass this a /// parameter (see [DataSource]). - pub fn extract_data( - &self, - start: u64, - end: u64, - last_update: f64, - ) -> (u64, u64, Vec>) { + pub fn extract_data(&self, start: u64, end: u64, last_update: f64) -> Entry { let last_update = last_update as u64; let reso = self.resolution; let num_entries = self.data.len() as u64; @@ -303,7 +334,7 @@ impl RRA { } } - (start, reso, list) + Entry::new(start, reso, list) } } @@ -464,7 +495,7 @@ impl RRD { resolution: u64, start: Option, end: Option, - ) -> Result<(u64, u64, Vec>), Error> { + ) -> Result { let mut rra: Option<&RRA> = None; for item in self.rra_list.iter() { if item.cf != cf { @@ -507,9 +538,13 @@ mod tests { rrd.update((i as f64) * 30.0, i as f64); } - let (start, reso, data) = rrd.extract_data(CF::Maximum, 60, Some(0), Some(5 * 60))?; + let Entry { + start, + resolution, + data, + } = rrd.extract_data(CF::Maximum, 60, Some(0), Some(5 * 60))?; assert_eq!(start, 0); - assert_eq!(reso, 60); + assert_eq!(resolution, 60); assert_eq!(data, [None, Some(3.0), Some(5.0), Some(7.0), Some(9.0)]); Ok(()) @@ -524,9 +559,13 @@ mod tests { rrd.update((i as f64) * 30.0, i as f64); } - let (start, reso, data) = rrd.extract_data(CF::Minimum, 60, Some(0), Some(5 * 60))?; + let Entry { + start, + resolution, + data, + } = rrd.extract_data(CF::Minimum, 60, Some(0), Some(5 * 60))?; assert_eq!(start, 0); - assert_eq!(reso, 60); + assert_eq!(resolution, 60); assert_eq!(data, [None, Some(2.0), Some(4.0), Some(6.0), Some(8.0)]); Ok(()) @@ -547,9 +586,13 @@ mod tests { "CF::Average should not exist" ); - let (start, reso, data) = rrd.extract_data(CF::Last, 60, Some(0), Some(20 * 60))?; + let Entry { + start, + resolution, + data, + } = rrd.extract_data(CF::Last, 60, Some(0), Some(20 * 60))?; assert_eq!(start, 0); - assert_eq!(reso, 60); + assert_eq!(resolution, 60); assert_eq!(data, [None, Some(3.0), Some(5.0), Some(7.0), Some(9.0)]); Ok(()) @@ -564,9 +607,13 @@ mod tests { rrd.update((i as f64) * 30.0, (i * 60) as f64); } - let (start, reso, data) = rrd.extract_data(CF::Average, 60, Some(60), Some(5 * 60))?; + let Entry { + start, + resolution, + data, + } = rrd.extract_data(CF::Average, 60, Some(60), Some(5 * 60))?; assert_eq!(start, 60); - assert_eq!(reso, 60); + assert_eq!(resolution, 60); assert_eq!(data, [Some(1.0), Some(2.0), Some(2.0), Some(2.0), None]); Ok(()) @@ -581,23 +628,35 @@ mod tests { rrd.update((i as f64) * 30.0, i as f64); } - let (start, reso, data) = rrd.extract_data(CF::Average, 60, Some(60), Some(5 * 60))?; + let Entry { + start, + resolution, + data, + } = rrd.extract_data(CF::Average, 60, Some(60), Some(5 * 60))?; assert_eq!(start, 60); - assert_eq!(reso, 60); + assert_eq!(resolution, 60); assert_eq!(data, [Some(2.5), Some(4.5), Some(6.5), Some(8.5), None]); for i in 10..14 { rrd.update((i as f64) * 30.0, i as f64); } - let (start, reso, data) = rrd.extract_data(CF::Average, 60, Some(60), Some(5 * 60))?; + let Entry { + start, + resolution, + data, + } = rrd.extract_data(CF::Average, 60, Some(60), Some(5 * 60))?; assert_eq!(start, 60); - assert_eq!(reso, 60); + assert_eq!(resolution, 60); assert_eq!(data, [None, Some(4.5), Some(6.5), Some(8.5), Some(10.5)]); - let (start, reso, data) = rrd.extract_data(CF::Average, 60, Some(3 * 60), Some(8 * 60))?; + let Entry { + start, + resolution, + data, + } = rrd.extract_data(CF::Average, 60, Some(3 * 60), Some(8 * 60))?; assert_eq!(start, 3 * 60); - assert_eq!(reso, 60); + assert_eq!(resolution, 60); assert_eq!(data, [Some(6.5), Some(8.5), Some(10.5), Some(12.5), None]); // add much newer value (should delete all previous/outdated value) @@ -605,16 +664,23 @@ mod tests { rrd.update((i as f64) * 30.0, i as f64); println!("TEST {:?}", serde_json::to_string_pretty(&rrd)); - let (start, reso, data) = - rrd.extract_data(CF::Average, 60, Some(100 * 30), Some(100 * 30 + 5 * 60))?; + let Entry { + start, + resolution, + data, + } = rrd.extract_data(CF::Average, 60, Some(100 * 30), Some(100 * 30 + 5 * 60))?; assert_eq!(start, 100 * 30); - assert_eq!(reso, 60); + assert_eq!(resolution, 60); assert_eq!(data, [Some(100.0), None, None, None, None]); // extract with end time smaller than start time - let (start, reso, data) = rrd.extract_data(CF::Average, 60, Some(100 * 30), Some(60))?; + let Entry { + start, + resolution, + data, + } = rrd.extract_data(CF::Average, 60, Some(100 * 30), Some(60))?; assert_eq!(start, 100 * 30); - assert_eq!(reso, 60); + assert_eq!(resolution, 60); assert_eq!(data, []); Ok(())