rrd: try to load database if not already present in cache
Before, a call to `update` was necessary to load an existing database into the cache. If `update` was never called, `extract_cached_data` would simply return no data. Signed-off-by: Lukas Wagner <l.wagner@proxmox.com>
This commit is contained in:
parent
f01c1e0ce9
commit
7ea63a6fb9
@ -12,7 +12,7 @@ use crossbeam_channel::{bounded, TryRecvError};
|
||||
|
||||
use proxmox_sys::fs::{create_path, CreateOptions};
|
||||
|
||||
use crate::rrd::{AggregationFn, Archive, DataSourceType, Database};
|
||||
use crate::rrd::{AggregationFn, DataSourceType, Database};
|
||||
use crate::Entry;
|
||||
|
||||
mod journal;
|
||||
@ -58,7 +58,8 @@ impl Cache {
|
||||
file_options: Option<CreateOptions>,
|
||||
dir_options: Option<CreateOptions>,
|
||||
apply_interval: f64,
|
||||
load_rrd_cb: fn(path: &Path, rel_path: &str, dst: DataSourceType) -> Database,
|
||||
load_rrd_cb: fn(path: &Path, rel_path: &str) -> Option<Database>,
|
||||
create_rrd_cb: fn(dst: DataSourceType) -> Database,
|
||||
) -> Result<Self, Error> {
|
||||
let basedir = basedir.as_ref().to_owned();
|
||||
|
||||
@ -80,7 +81,7 @@ impl Cache {
|
||||
});
|
||||
|
||||
let state = JournalState::new(Arc::clone(&config))?;
|
||||
let rrd_map = RRDMap::new(Arc::clone(&config), load_rrd_cb);
|
||||
let rrd_map = RRDMap::new(Arc::clone(&config), load_rrd_cb, create_rrd_cb);
|
||||
|
||||
Ok(Self {
|
||||
config: Arc::clone(&config),
|
||||
@ -248,10 +249,24 @@ impl Cache {
|
||||
start: Option<u64>,
|
||||
end: Option<u64>,
|
||||
) -> Result<Option<Entry>, Error> {
|
||||
self.rrd_map
|
||||
.read()
|
||||
.unwrap()
|
||||
.extract_cached_data(base, name, cf, resolution, start, end)
|
||||
let res = {
|
||||
let map = self.rrd_map.read().unwrap();
|
||||
map.extract_cached_data(base, name, cf, resolution, start, end)?
|
||||
};
|
||||
|
||||
match res {
|
||||
Some(entry) => Ok(Some(entry)),
|
||||
None => {
|
||||
let mut map = self.rrd_map.write().unwrap();
|
||||
let loaded = map.load(&format!("{base}/{name}"))?;
|
||||
|
||||
if loaded {
|
||||
map.extract_cached_data(base, name, cf, resolution, start, end)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
41
proxmox-rrd/src/cache/rrd_map.rs
vendored
41
proxmox-rrd/src/cache/rrd_map.rs
vendored
@ -14,18 +14,21 @@ use crate::Entry;
|
||||
pub struct RRDMap {
|
||||
config: Arc<CacheConfig>,
|
||||
map: HashMap<String, Database>,
|
||||
load_rrd_cb: fn(path: &Path, rel_path: &str, dst: DataSourceType) -> Database,
|
||||
load_rrd_cb: fn(path: &Path, rel_path: &str) -> Option<Database>,
|
||||
create_rrd_cb: fn(dst: DataSourceType) -> Database,
|
||||
}
|
||||
|
||||
impl RRDMap {
|
||||
pub(crate) fn new(
|
||||
config: Arc<CacheConfig>,
|
||||
load_rrd_cb: fn(path: &Path, rel_path: &str, dst: DataSourceType) -> Database,
|
||||
load_rrd_cb: fn(path: &Path, rel_path: &str) -> Option<Database>,
|
||||
create_rrd_cb: fn(dst: DataSourceType) -> Database,
|
||||
) -> Self {
|
||||
Self {
|
||||
config,
|
||||
map: HashMap::new(),
|
||||
load_rrd_cb,
|
||||
create_rrd_cb,
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,13 +47,18 @@ impl RRDMap {
|
||||
} 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 = match (self.load_rrd_cb)(&path, rel_path) {
|
||||
None => {
|
||||
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);
|
||||
(self.create_rrd_cb)(dst)
|
||||
}
|
||||
Some(rrd) => rrd,
|
||||
};
|
||||
|
||||
if !new_only || time > rrd.last_update() {
|
||||
rrd.update(time, value);
|
||||
@ -94,4 +102,21 @@ impl RRDMap {
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load(&mut self, rel_path: &str) -> Result<bool, Error> {
|
||||
if self.map.get(rel_path).is_some() {
|
||||
// Already loaded, do nothing
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
let mut path = self.config.basedir.clone();
|
||||
path.push(rel_path);
|
||||
|
||||
if let Some(rrd) = (self.load_rrd_cb)(&path, rel_path) {
|
||||
self.map.insert(rel_path.to_string(), rrd);
|
||||
return Ok(true);
|
||||
} else {
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user