use std::cell::RefCell;
use std::collections::BTreeMap;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Mutex;
static ENABLED: AtomicBool = AtomicBool::new(false);
static COUNTS: Mutex<BTreeMap<(&'static str, String), u64>> = Mutex::new(BTreeMap::new());
thread_local! {
static LOCAL: RefCell<BTreeMap<(&'static str, String), u64>> =
const { RefCell::new(BTreeMap::new()) };
}
pub fn enable(on: bool) {
ENABLED.store(on, Ordering::Relaxed);
}
pub(crate) fn record(op: &'static str, key: &[u8]) {
if !ENABLED.load(Ordering::Relaxed) {
return;
}
let family = rushdb_types::keys::family_label(key);
LOCAL.with(|local| *local.borrow_mut().entry((op, family.clone())).or_default() += 1);
let mut counts = COUNTS
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
*counts.entry((op, family)).or_default() += 1;
}
#[must_use]
pub fn take_local() -> BTreeMap<(&'static str, String), u64> {
LOCAL.with(|local| std::mem::take(&mut *local.borrow_mut()))
}
#[must_use]
pub fn take() -> BTreeMap<(&'static str, String), u64> {
std::mem::take(
&mut *COUNTS
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner),
)
}