use std::sync::Arc;
use std::sync::atomic::AtomicU64;
use std::sync::atomic::Ordering;
#[derive(Clone)]
pub struct Gauge(Arc<AtomicU64>);
impl std::fmt::Debug for Gauge {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("Gauge").field(&self.value()).finish()
}
}
impl Gauge {
pub(crate) fn new() -> Self {
Self(Default::default())
}
pub fn increment(&self, value: f64) {
loop {
if self
.0
.fetch_update(Ordering::AcqRel, Ordering::Relaxed, |current| {
let input = f64::from_bits(current);
Some((input + value).to_bits())
})
.is_ok()
{
break;
}
}
}
pub fn decrement(&self, value: f64) {
loop {
if self
.0
.fetch_update(Ordering::AcqRel, Ordering::Relaxed, |current| {
let input = f64::from_bits(current);
Some((input - value).to_bits())
})
.is_ok()
{
break;
}
}
}
pub fn set(&self, value: f64) {
_ = self.0.swap(value.to_bits(), Ordering::AcqRel);
}
pub fn value(&self) -> f64 {
let value = self.0.load(Ordering::Acquire);
f64::from_bits(value)
}
}