use crate::error::tracer::{DynTracerError, TracerError};
use crate::time::duration::Duration;
use spin::lock_api::{RwLock, RwLockReadGuard, RwLockWriteGuard};
#[derive(Debug, Default)]
pub struct CacheWrapper(RwLock<Cache>);
impl CacheWrapper {
#[allow(unused)]
pub fn new() -> Self {
Self(RwLock::new(Cache::default()))
}
pub fn clear(&self) {
(Ok(self.0.write()) as Result<RwLockWriteGuard<'_, Cache>, DynTracerError>)
.and_then(|mut t| {
let t = &mut *t;
t.year = None;
t.month = None;
t.day = None;
t.hour = None;
t.minute = None;
t.second = None;
t.nanosecond = None;
t.day_of_week = None;
t.week = None;
t.day_of_year = None;
Ok(())
})
.ok();
}
pub fn set<D>(&self, key: CacheKey, value: i32, duration: D) -> (i32, Duration)
where
D: Into<Duration>,
{
let res = (value, duration.into());
self.cache_mut()
.map(|mut t| {
let res_clone = res.clone();
let t = &mut *t;
match key {
CacheKey::Year => {
t.year = Option::from(res_clone);
}
CacheKey::Month => {
t.month = Option::from(res_clone);
}
CacheKey::Day => {
t.day = Option::from(res_clone);
}
CacheKey::Hour => {
t.hour = Option::from(res_clone);
}
CacheKey::Minute => {
t.minute = Option::from(res_clone);
}
CacheKey::Second => {
t.second = Option::from(res_clone);
}
CacheKey::Millisecond => {
t.millisecond = Option::from(res_clone);
}
CacheKey::Microseconds => {
t.microseconds = Option::from(res_clone);
}
CacheKey::Nanosecond => {
t.nanosecond = Option::from(res_clone);
}
CacheKey::DayOfWeek => {
t.day_of_week = Option::from(res_clone);
}
CacheKey::Week => {
t.week = Option::from(res_clone);
}
CacheKey::DayOfYear => {
t.day_of_year = Option::from(res_clone);
}
CacheKey::DayOfMonth => {
t.day_of_month = Option::from(res_clone);
}
}
})
.ok();
res
}
pub fn get(&self, key: CacheKey) -> Option<(i32, Duration)> {
self.cache()
.map(|t| match key {
CacheKey::Year => t.year.clone(),
CacheKey::Month => t.month.clone(),
CacheKey::Day => t.day.clone(),
CacheKey::Hour => t.hour.clone(),
CacheKey::Minute => t.minute.clone(),
CacheKey::Second => t.second.clone(),
CacheKey::Millisecond => t.millisecond.clone(),
CacheKey::Microseconds => t.microseconds.clone(),
CacheKey::Nanosecond => t.nanosecond.clone(),
CacheKey::DayOfWeek => t.day_of_week.clone(),
CacheKey::Week => t.week.clone(),
CacheKey::DayOfYear => t.day_of_year.clone(),
CacheKey::DayOfMonth => t.day_of_month.clone(),
})
.unwrap_or(None)
}
fn cache(&self) -> Result<RwLockReadGuard<'_, Cache>, DynTracerError> {
Ok(self.0.read())
}
fn cache_mut(&self) -> Result<RwLockWriteGuard<'_, Cache>, DynTracerError> {
Ok(self.0.write())
}
}
impl Clone for CacheWrapper {
fn clone(&self) -> Self {
self.cache()
.map(|t| Self(RwLock::new(t.clone())))
.unwrap_or_default()
}
}
pub enum CacheKey {
Year,
Month,
#[allow(unused)]
Day,
Hour,
Minute,
Second,
Millisecond,
Microseconds,
#[allow(unused)]
Nanosecond,
#[allow(unused)]
DayOfWeek,
#[allow(unused)]
Week,
#[allow(unused)]
DayOfYear,
DayOfMonth,
}
#[derive(Debug, Clone)]
pub struct Cache {
pub(super) year: Option<(i32, Duration)>,
pub(super) month: Option<(i32, Duration)>,
pub(super) day: Option<(i32, Duration)>,
pub(super) hour: Option<(i32, Duration)>,
pub(super) minute: Option<(i32, Duration)>,
pub(super) second: Option<(i32, Duration)>,
pub(super) millisecond: Option<(i32, Duration)>,
pub(super) microseconds: Option<(i32, Duration)>,
pub(super) nanosecond: Option<(i32, Duration)>,
pub(super) day_of_week: Option<(i32, Duration)>,
pub(super) week: Option<(i32, Duration)>,
pub(super) day_of_year: Option<(i32, Duration)>,
pub(super) day_of_month: Option<(i32, Duration)>,
}
impl Default for Cache {
fn default() -> Self {
Self {
year: None,
month: None,
day: None,
hour: None,
minute: None,
second: None,
millisecond: None,
microseconds: None,
nanosecond: None,
day_of_week: None,
week: None,
day_of_year: None,
day_of_month: None,
}
}
}