]>
Commit | Line | Data |
---|---|---|
d5b9d1f4 | 1 | use std::collections::HashMap; |
4393b93a DM |
2 | use std::path::Path; |
3 | use std::sync::Arc; | |
4393b93a DM |
4 | |
5 | use anyhow::{bail, Error}; | |
6 | ||
a092ef9c | 7 | use proxmox_sys::fs::create_path; |
4393b93a | 8 | |
2f942833 | 9 | use crate::rrd::{AggregationFn, DataSourceType, Database}; |
4393b93a DM |
10 | |
11 | use super::CacheConfig; | |
56b5c289 | 12 | use crate::Entry; |
4393b93a DM |
13 | |
14 | pub struct RRDMap { | |
15 | config: Arc<CacheConfig>, | |
2f942833 LW |
16 | map: HashMap<String, Database>, |
17 | load_rrd_cb: fn(path: &Path, rel_path: &str, dst: DataSourceType) -> Database, | |
4393b93a DM |
18 | } |
19 | ||
20 | impl RRDMap { | |
4393b93a DM |
21 | pub(crate) fn new( |
22 | config: Arc<CacheConfig>, | |
2f942833 | 23 | load_rrd_cb: fn(path: &Path, rel_path: &str, dst: DataSourceType) -> Database, |
4393b93a DM |
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, | |
2f942833 | 37 | dst: DataSourceType, |
4393b93a DM |
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 | ||
77c2e466 DM |
63 | pub fn file_list(&self) -> Vec<String> { |
64 | let mut list = Vec::new(); | |
4393b93a | 65 | |
77c2e466 DM |
66 | for rel_path in self.map.keys() { |
67 | list.push(rel_path.clone()); | |
4393b93a DM |
68 | } |
69 | ||
77c2e466 DM |
70 | list |
71 | } | |
4393b93a | 72 | |
77c2e466 | 73 | pub fn flush_rrd_file(&self, rel_path: &str) -> Result<(), Error> { |
d5b9d1f4 | 74 | if let Some(rrd) = self.map.get(rel_path) { |
77c2e466 DM |
75 | let mut path = self.config.basedir.clone(); |
76 | path.push(rel_path); | |
75bb60e7 | 77 | rrd.save(&path, self.config.file_options.clone(), true) |
77c2e466 DM |
78 | } else { |
79 | bail!("rrd file {} not loaded", rel_path); | |
80 | } | |
4393b93a DM |
81 | } |
82 | ||
83 | pub fn extract_cached_data( | |
84 | &self, | |
85 | base: &str, | |
86 | name: &str, | |
2f942833 | 87 | cf: AggregationFn, |
4393b93a DM |
88 | resolution: u64, |
89 | start: Option<u64>, | |
90 | end: Option<u64>, | |
56b5c289 | 91 | ) -> Result<Option<Entry>, Error> { |
4393b93a DM |
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 | } |