use std::sync::atomic::{AtomicU64, Ordering};
#[allow(clippy::struct_field_names)] pub(crate) struct HnswSafetyCounters {
#[allow(dead_code)] pub lock_contention_total: AtomicU64,
#[allow(dead_code)] pub operation_retry_total: AtomicU64,
pub invariant_violation_total: AtomicU64,
pub corruption_detected_total: AtomicU64,
}
impl HnswSafetyCounters {
#[allow(dead_code)] #[must_use]
pub const fn new() -> Self {
Self {
lock_contention_total: AtomicU64::new(0),
operation_retry_total: AtomicU64::new(0),
invariant_violation_total: AtomicU64::new(0),
corruption_detected_total: AtomicU64::new(0),
}
}
#[allow(dead_code)] #[inline]
pub fn record_contention(&self) {
self.lock_contention_total.fetch_add(1, Ordering::Relaxed);
}
#[allow(dead_code)] #[inline]
pub fn record_retry(&self) {
self.operation_retry_total.fetch_add(1, Ordering::Relaxed);
}
#[allow(dead_code)] #[inline]
pub fn record_invariant_violation(&self) {
self.invariant_violation_total
.fetch_add(1, Ordering::Relaxed);
}
#[allow(dead_code)] #[inline]
pub fn record_corruption(&self) {
self.corruption_detected_total
.fetch_add(1, Ordering::Relaxed);
}
#[allow(dead_code)] #[must_use]
pub fn snapshot(&self) -> CounterSnapshot {
CounterSnapshot {
lock_contention_total: self.lock_contention_total.load(Ordering::Relaxed),
operation_retry_total: self.operation_retry_total.load(Ordering::Relaxed),
invariant_violation_total: self.invariant_violation_total.load(Ordering::Relaxed),
corruption_detected_total: self.corruption_detected_total.load(Ordering::Relaxed),
}
}
}
#[allow(dead_code)] #[derive(Debug, Clone, Copy)]
#[allow(clippy::struct_field_names)] pub(crate) struct CounterSnapshot {
pub lock_contention_total: u64,
pub operation_retry_total: u64,
pub invariant_violation_total: u64,
pub corruption_detected_total: u64,
}
#[allow(dead_code)] pub(crate) static HNSW_COUNTERS: HnswSafetyCounters = HnswSafetyCounters::new();