From 45700e2ecf76fdfebc3f58d962ce25d5a513097c Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Sat, 16 Oct 2021 12:22:40 +0200 Subject: [PATCH] proxmox-rrd: move RRDMap into extra file --- proxmox-rrd/src/cache.rs | 93 +--------------------------- proxmox-rrd/src/cache/rrd_map.rs | 100 +++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 90 deletions(-) create mode 100644 proxmox-rrd/src/cache/rrd_map.rs diff --git a/proxmox-rrd/src/cache.rs b/proxmox-rrd/src/cache.rs index 0b7aa0de..afe7a33c 100644 --- a/proxmox-rrd/src/cache.rs +++ b/proxmox-rrd/src/cache.rs @@ -1,6 +1,5 @@ use std::fs::File; use std::path::{Path, PathBuf}; -use std::collections::HashMap; use std::sync::{Arc, RwLock}; use std::io::{BufRead, BufReader}; use std::time::SystemTime; @@ -15,6 +14,9 @@ use crate::rrd::{DST, CF, RRD, RRA}; mod journal; use journal::*; +mod rrd_map; +use rrd_map::*; + /// RRD cache - keep RRD data in RAM, but write updates to disk /// /// This cache is designed to run as single instance (no concurrent @@ -32,95 +34,6 @@ pub(crate) struct CacheConfig { dir_options: CreateOptions, } -struct RRDMap { - config: Arc, - map: HashMap, - load_rrd_cb: fn(path: &Path, rel_path: &str, dst: DST) -> RRD, -} - -impl RRDMap { - - fn new( - config: Arc, - load_rrd_cb: fn(path: &Path, rel_path: &str, dst: DST) -> RRD, - ) -> Self { - Self { - config, - map: HashMap::new(), - load_rrd_cb, - } - } - - fn update( - &mut self, - rel_path: &str, - time: f64, - value: f64, - dst: DST, - new_only: bool, - ) -> Result<(), Error> { - if let Some(rrd) = self.map.get_mut(rel_path) { - if !new_only || time > rrd.last_update() { - rrd.update(time, value); - } - } else { - let mut path = self.config.basedir.clone(); - path.push(rel_path); - create_path( - path.parent().unwrap(), - Some(self.config.dir_options.clone()), - Some(self.config.dir_options.clone()), - )?; - - let mut rrd = (self.load_rrd_cb)(&path, rel_path, dst); - - if !new_only || time > rrd.last_update() { - rrd.update(time, value); - } - self.map.insert(rel_path.to_string(), rrd); - } - Ok(()) - } - - fn flush_rrd_files(&self) -> Result { - let mut rrd_file_count = 0; - - let mut errors = 0; - for (rel_path, rrd) in self.map.iter() { - rrd_file_count += 1; - - let mut path = self.config.basedir.clone(); - path.push(&rel_path); - - if let Err(err) = rrd.save(&path, self.config.file_options.clone()) { - errors += 1; - log::error!("unable to save {:?}: {}", path, err); - } - } - - if errors != 0 { - bail!("errors during rrd flush - unable to commit rrd journal"); - } - - Ok(rrd_file_count) - } - - fn extract_cached_data( - &self, - base: &str, - name: &str, - cf: CF, - resolution: u64, - start: Option, - end: Option, - ) -> Result>)>, Error> { - match self.map.get(&format!("{}/{}", base, name)) { - Some(rrd) => Ok(Some(rrd.extract_data(cf, resolution, start, end)?)), - None => Ok(None), - } - } -} - impl RRDCache { diff --git a/proxmox-rrd/src/cache/rrd_map.rs b/proxmox-rrd/src/cache/rrd_map.rs new file mode 100644 index 00000000..27c5ae1c --- /dev/null +++ b/proxmox-rrd/src/cache/rrd_map.rs @@ -0,0 +1,100 @@ +use std::path::Path; +use std::sync::Arc; +use std::collections::HashMap; + +use anyhow::{bail, Error}; + +use proxmox::tools::fs::create_path; + +use crate::rrd::{CF, DST, RRD}; + +use super::CacheConfig; + +pub struct RRDMap { + config: Arc, + map: HashMap, + load_rrd_cb: fn(path: &Path, rel_path: &str, dst: DST) -> RRD, +} + +impl RRDMap { + + pub(crate) fn new( + config: Arc, + load_rrd_cb: fn(path: &Path, rel_path: &str, dst: DST) -> RRD, + ) -> Self { + Self { + config, + map: HashMap::new(), + load_rrd_cb, + } + } + + pub fn update( + &mut self, + rel_path: &str, + time: f64, + value: f64, + dst: DST, + new_only: bool, + ) -> Result<(), Error> { + if let Some(rrd) = self.map.get_mut(rel_path) { + if !new_only || time > rrd.last_update() { + rrd.update(time, value); + } + } else { + let mut path = self.config.basedir.clone(); + path.push(rel_path); + create_path( + path.parent().unwrap(), + Some(self.config.dir_options.clone()), + Some(self.config.dir_options.clone()), + )?; + + let mut rrd = (self.load_rrd_cb)(&path, rel_path, dst); + + if !new_only || time > rrd.last_update() { + rrd.update(time, value); + } + self.map.insert(rel_path.to_string(), rrd); + } + Ok(()) + } + + pub fn flush_rrd_files(&self) -> Result { + let mut rrd_file_count = 0; + + let mut errors = 0; + for (rel_path, rrd) in self.map.iter() { + rrd_file_count += 1; + + let mut path = self.config.basedir.clone(); + path.push(&rel_path); + + if let Err(err) = rrd.save(&path, self.config.file_options.clone()) { + errors += 1; + log::error!("unable to save {:?}: {}", path, err); + } + } + + if errors != 0 { + bail!("errors during rrd flush - unable to commit rrd journal"); + } + + Ok(rrd_file_count) + } + + pub fn extract_cached_data( + &self, + base: &str, + name: &str, + cf: CF, + resolution: u64, + start: Option, + end: Option, + ) -> Result>)>, Error> { + match self.map.get(&format!("{}/{}", base, name)) { + Some(rrd) => Ok(Some(rrd.extract_data(cf, resolution, start, end)?)), + None => Ok(None), + } + } +}