use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
use once_cell::sync::OnceCell;
use scc::{ebr::Guard, HashIndex};
use snapshot::{FlushParams, StatsSnapshot};
use stat::*;
pub extern crate hdrhistogram;
pub type HdrHistogram = crate::hdrhistogram::Histogram<u64>;
pub mod scheduler;
pub mod snapshot;
pub mod stat;
#[derive(Debug)]
pub struct Stats {
counters: HashIndex<String, Arc<Counter>>,
gauges_f64: HashIndex<String, Arc<GaugeF64>>,
gauges_i64: HashIndex<String, Arc<GaugeI64>>,
histograms: HashIndex<String, Arc<Histogram>>,
sets: HashIndex<String, Arc<Set>>,
default_reset_on_flush_for_counters: AtomicBool,
default_reset_on_flush_for_gauges: AtomicBool,
default_reset_on_flush_for_histograms: AtomicBool,
default_reset_on_flush_for_sets: AtomicBool,
}
impl Stats {
pub fn global() -> &'static Arc<Stats> {
static INSTANCE: OnceCell<Arc<Stats>> = OnceCell::new();
INSTANCE.get_or_init(|| Arc::new(Stats::new()))
}
pub fn new() -> Self {
Self {
counters: HashIndex::new(),
gauges_f64: HashIndex::new(),
gauges_i64: HashIndex::new(),
histograms: HashIndex::new(),
sets: HashIndex::new(),
default_reset_on_flush_for_counters: AtomicBool::new(false),
default_reset_on_flush_for_gauges: AtomicBool::new(false),
default_reset_on_flush_for_histograms: AtomicBool::new(false),
default_reset_on_flush_for_sets: AtomicBool::new(false),
}
}
pub fn counter<'a, N: Into<String>>(&self, name: N) -> Arc<Counter> {
Arc::clone(
&self
.counters
.entry(name.into())
.or_insert_with(|| {
Arc::new(Counter::new(
self.default_reset_on_flush_for_counters
.load(Ordering::Relaxed),
))
})
.get(),
)
}
pub fn gauge_f64<'a, N: Into<String>>(&self, name: N) -> Arc<GaugeF64> {
Arc::clone(
&self
.gauges_f64
.entry(name.into())
.or_insert_with(|| {
Arc::new(GaugeF64::new(
self.default_reset_on_flush_for_gauges
.load(Ordering::Relaxed),
))
})
.get(),
)
}
pub fn gauge_i64<'a, N: Into<String>>(&self, name: N) -> Arc<GaugeI64> {
Arc::clone(
&self
.gauges_i64
.entry(name.into())
.or_insert_with(|| {
Arc::new(GaugeI64::new(
self.default_reset_on_flush_for_gauges
.load(Ordering::Relaxed),
))
})
.get(),
)
}
pub fn histogram<'a, N: Into<String>>(&self, name: N) -> Arc<Histogram> {
Arc::clone(
&self
.histograms
.entry(name.into())
.or_insert_with(|| {
Arc::new(Histogram::new(
self.default_reset_on_flush_for_histograms
.load(Ordering::Relaxed),
))
})
.get(),
)
}
pub fn set<'a, N: Into<String>>(&self, name: N) -> Arc<Set> {
Arc::clone(
&self
.sets
.entry(name.into())
.or_insert_with(|| {
Arc::new(Set::new(
self.default_reset_on_flush_for_sets.load(Ordering::Relaxed),
))
})
.get(),
)
}
pub fn flush(&self, params: &FlushParams) -> StatsSnapshot {
let mut snapshot = StatsSnapshot::default();
let guard = Guard::new();
self.counters.iter(&guard).for_each(|(k, v)| {
snapshot.counters.insert(k.clone(), v.flush());
});
self.gauges_f64.iter(&guard).for_each(|(k, v)| {
snapshot.gauges_f64.insert(k.clone(), v.flush());
});
self.gauges_i64.iter(&guard).for_each(|(k, v)| {
snapshot.gauges_i64.insert(k.clone(), v.flush());
});
self.histograms.iter(&guard).for_each(|(k, v)| {
snapshot
.histograms
.insert(k.clone(), v.flush(¶ms.histogram_percentiles));
});
self.sets.iter(&guard).for_each(|(k, v)| {
snapshot.sets.insert(k.clone(), v.flush());
});
snapshot
}
pub fn evict(&self) {
self.counters.retain(|_, v| Arc::strong_count(v) > 1);
self.gauges_f64.retain(|_, v| Arc::strong_count(v) > 1);
self.gauges_i64.retain(|_, v| Arc::strong_count(v) > 1);
self.histograms.retain(|_, v| Arc::strong_count(v) > 1);
self.sets.retain(|_, v| Arc::strong_count(v) > 1);
}
pub fn set_default_reset_on_flush_for_counters(&self, val: bool) {
self.default_reset_on_flush_for_counters
.store(val, Ordering::Relaxed);
}
pub fn set_default_reset_on_flush_for_gauges(&self, val: bool) {
self.default_reset_on_flush_for_gauges
.store(val, Ordering::Relaxed);
}
pub fn set_default_reset_on_flush_for_histograms(&self, val: bool) {
self.default_reset_on_flush_for_histograms
.store(val, Ordering::Relaxed);
}
pub fn set_default_reset_on_flush_for_sets(&self, val: bool) {
self.default_reset_on_flush_for_sets
.store(val, Ordering::Relaxed);
}
}