use std::sync::Arc;
use std::time::SystemTime;
use dashmap::DashMap;
use crate::stats::stats_item::StatsItem;
use crate::stats::stats_snapshot::StatsSnapshot;
#[derive(Clone, Debug)]
pub struct StatsItemSet {
stats_name: String,
items: Arc<DashMap<String, Arc<StatsItem>>>,
}
impl StatsItemSet {
pub fn new(stats_name: String) -> Self {
StatsItemSet {
stats_name,
items: Arc::new(DashMap::new()),
}
}
pub fn get_or_create_stats_item(&self, key: &str) -> Arc<StatsItem> {
if let Some(item) = self.items.get(key) {
return Arc::clone(&*item);
}
self.items
.entry(key.to_string())
.or_insert_with(|| Arc::new(StatsItem::new(&self.stats_name, key)))
.clone()
}
pub fn add_value(&self, stats_key: &str, inc_value: impl Into<i64>, inc_times: impl Into<i64>) {
let item = self.get_or_create_stats_item(stats_key);
item.add(inc_value.into() as u64, inc_times.into() as u64);
}
pub fn add_rt_value(&self, stats_key: &str, inc_value: impl Into<i64>, inc_times: impl Into<i64>) {
self.add_value(stats_key, inc_value.into(), inc_times.into());
}
pub fn get_stats_data_in_minute(&self, stats_key: &str) -> StatsSnapshot {
self.items
.get(stats_key)
.map(|item| item.get_stats_data_in_minute())
.unwrap_or_default()
}
pub fn get_stats_data_in_hour(&self, stats_key: &str) -> StatsSnapshot {
self.items
.get(stats_key)
.map(|item| item.get_stats_data_in_hour())
.unwrap_or_default()
}
pub fn get_stats_item(&self, stats_key: &str) -> Option<Arc<StatsItem>> {
self.items.get(stats_key).map(|entry| entry.clone())
}
pub fn sampling_in_seconds(&self) {
for entry in self.items.iter() {
entry.value().sampling_in_seconds();
}
}
pub fn sampling_in_minutes(&self) {
for entry in self.items.iter() {
entry.value().sampling_in_minutes_level();
}
}
pub fn sampling_in_hours(&self) {
for entry in self.items.iter() {
entry.value().sampling_in_hour_level();
}
}
pub fn del_value(&self, key: &str) {
self.items.remove(key);
}
pub fn del_value_by_prefix_key(&self, prefix: &str, separator: &str) {
let match_prefix = format!("{}{}", prefix, separator);
self.items.retain(|k, _| !k.starts_with(&match_prefix));
}
pub fn del_value_by_suffix_key(&self, suffix: &str, separator: &str) {
let match_suffix = format!("{}{}", separator, suffix);
self.items.retain(|k, _| !k.ends_with(&match_suffix));
}
pub fn del_value_by_infix_key(&self, infix: &str, separator: &str) {
let pattern = format!("{}{}{}", separator, infix, separator);
self.items.retain(|k, _| !k.contains(&pattern));
}
pub fn size(&self) -> usize {
self.items.len()
}
pub fn clear(&self) {
self.items.clear();
}
pub fn clean_resource(&self, max_idle_minutes: u64) {
let now = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap_or_default()
.as_millis() as u64;
let threshold_ms = max_idle_minutes * 60 * 1000;
self.items
.retain(|_, v| now.saturating_sub(v.get_last_update_timestamp()) <= threshold_ms);
}
}