vector_common/
atomic.rs

1use std::sync::atomic::{AtomicU64, Ordering};
2
3use metrics::GaugeFn;
4
5/// Simple atomic wrapper for `f64` values.
6#[derive(Debug)]
7pub struct AtomicF64(AtomicU64);
8
9impl AtomicF64 {
10    /// Creates a new `AtomicF64` with the given initial value.
11    #[must_use]
12    pub fn new(init: f64) -> Self {
13        Self(AtomicU64::new(init.to_bits()))
14    }
15
16    pub fn load(&self, order: Ordering) -> f64 {
17        f64::from_bits(self.0.load(order))
18    }
19
20    #[expect(clippy::missing_panics_doc, reason = "fetch_update always succeeds")]
21    pub fn fetch_update(
22        &self,
23        set_order: Ordering,
24        fetch_order: Ordering,
25        mut f: impl FnMut(f64) -> f64,
26    ) -> f64 {
27        f64::from_bits(
28            self.0
29                .fetch_update(set_order, fetch_order, |x| {
30                    Some(f(f64::from_bits(x)).to_bits())
31                })
32                .expect("fetch_update always succeeds"),
33        )
34    }
35}
36
37impl GaugeFn for AtomicF64 {
38    fn increment(&self, amount: f64) {
39        self.fetch_update(Ordering::Relaxed, Ordering::Relaxed, |value| value + amount);
40    }
41
42    fn decrement(&self, amount: f64) {
43        self.fetch_update(Ordering::Relaxed, Ordering::Relaxed, |value| value - amount);
44    }
45
46    fn set(&self, value: f64) {
47        self.0.store(f64::to_bits(value), Ordering::Relaxed);
48    }
49}