#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum Point {
BeforeDiskWrite,
CompactionTailRead,
CompactionCopied,
BetweenStoreFiles,
}
#[cfg(test)]
type Hook = Box<dyn FnMut(Point)>;
#[cfg(test)]
thread_local! {
static HOOK: std::cell::RefCell<Option<Hook>> = const { std::cell::RefCell::new(None) };
}
#[inline]
pub(crate) fn fire(point: Point) {
#[cfg(test)]
{
let hook = HOOK.with(|h| h.borrow_mut().take());
if let Some(mut hook) = hook {
hook(point);
HOOK.with(|h| {
let mut slot = h.borrow_mut();
if slot.is_none() {
*slot = Some(hook);
}
});
}
}
#[cfg(not(test))]
let _ = point;
}
#[cfg(test)]
pub(crate) fn install(hook: impl FnMut(Point) + 'static) -> HookGuard {
HOOK.with(|h| *h.borrow_mut() = Some(Box::new(hook)));
HookGuard
}
#[cfg(test)]
pub(crate) struct HookGuard;
#[cfg(test)]
impl Drop for HookGuard {
fn drop(&mut self) {
HOOK.with(|h| *h.borrow_mut() = None);
}
}