]> git.proxmox.com Git - proxmox-backup.git/blob - proxmox-rrd/src/cache/rrd_map.rs
update to proxmox-sys 0.2 crate
[proxmox-backup.git] / proxmox-rrd / src / cache / rrd_map.rs
1 use std::path::Path;
2 use std::sync::Arc;
3 use std::collections::HashMap;
4
5 use anyhow::{bail, Error};
6
7 use proxmox_sys::fs::create_path;
8
9 use crate::rrd::{CF, DST, RRD};
10
11 use super::CacheConfig;
12
13 pub struct RRDMap {
14 config: Arc<CacheConfig>,
15 map: HashMap<String, RRD>,
16 load_rrd_cb: fn(path: &Path, rel_path: &str, dst: DST) -> RRD,
17 }
18
19 impl RRDMap {
20
21 pub(crate) fn new(
22 config: Arc<CacheConfig>,
23 load_rrd_cb: fn(path: &Path, rel_path: &str, dst: DST) -> RRD,
24 ) -> Self {
25 Self {
26 config,
27 map: HashMap::new(),
28 load_rrd_cb,
29 }
30 }
31
32 pub fn update(
33 &mut self,
34 rel_path: &str,
35 time: f64,
36 value: f64,
37 dst: DST,
38 new_only: bool,
39 ) -> Result<(), Error> {
40 if let Some(rrd) = self.map.get_mut(rel_path) {
41 if !new_only || time > rrd.last_update() {
42 rrd.update(time, value);
43 }
44 } else {
45 let mut path = self.config.basedir.clone();
46 path.push(rel_path);
47 create_path(
48 path.parent().unwrap(),
49 Some(self.config.dir_options.clone()),
50 Some(self.config.dir_options.clone()),
51 )?;
52
53 let mut rrd = (self.load_rrd_cb)(&path, rel_path, dst);
54
55 if !new_only || time > rrd.last_update() {
56 rrd.update(time, value);
57 }
58 self.map.insert(rel_path.to_string(), rrd);
59 }
60 Ok(())
61 }
62
63 pub fn file_list(&self) -> Vec<String> {
64 let mut list = Vec::new();
65
66 for rel_path in self.map.keys() {
67 list.push(rel_path.clone());
68 }
69
70 list
71 }
72
73 pub fn flush_rrd_file(&self, rel_path: &str) -> Result<(), Error> {
74 if let Some(rrd) = self.map.get(rel_path) {
75 let mut path = self.config.basedir.clone();
76 path.push(rel_path);
77 rrd.save(&path, self.config.file_options.clone(), true)
78 } else {
79 bail!("rrd file {} not loaded", rel_path);
80 }
81 }
82
83 pub fn extract_cached_data(
84 &self,
85 base: &str,
86 name: &str,
87 cf: CF,
88 resolution: u64,
89 start: Option<u64>,
90 end: Option<u64>,
91 ) -> Result<Option<(u64, u64, Vec<Option<f64>>)>, Error> {
92 match self.map.get(&format!("{}/{}", base, name)) {
93 Some(rrd) => Ok(Some(rrd.extract_data(cf, resolution, start, end)?)),
94 None => Ok(None),
95 }
96 }
97 }