use std::sync::atomic::{AtomicU64, Ordering};
#[derive(Default)]
pub(super) struct Telemetry {
cache_hits: AtomicU64,
cache_misses: AtomicU64,
full_blob_reads: AtomicU64,
point_full_blob_reads: AtomicU64,
scan_full_blob_reads: AtomicU64,
silent_full_blob_reads: AtomicU64,
optimistic_restarts: AtomicU64,
range_restarts: AtomicU64,
walker_ops: AtomicU64,
walker_blob_hops: AtomicU64,
max_blob_hops: AtomicU64,
max_cross_blob_depth: AtomicU64,
spillover_count: AtomicU64,
merge_count: AtomicU64,
route_resident_demotions: AtomicU64,
cache_evictions: AtomicU64,
eviction_skips_protected: AtomicU64,
eviction_skips_route_resident: AtomicU64,
admission_protects: AtomicU64,
read_page_hits: AtomicU64,
read_page_misses: AtomicU64,
read_index_cache_hits: AtomicU64,
read_index_cache_misses: AtomicU64,
read_index_loads: AtomicU64,
read_index_dir_read_bytes: AtomicU64,
read_index_bucket_reads: AtomicU64,
read_index_bucket_read_bytes: AtomicU64,
read_index_inline_hits: AtomicU64,
read_index_value_hits: AtomicU64,
read_index_value_read_bytes: AtomicU64,
read_index_offset_hits: AtomicU64,
read_index_negative_hits: AtomicU64,
read_index_crossing_hits: AtomicU64,
read_index_unknowns: AtomicU64,
}
impl Telemetry {
pub(super) fn note_cache_hit(&self) {
self.cache_hits.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_cache_miss(&self) {
self.cache_misses.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_point_full_blob_read(&self) {
self.full_blob_reads.fetch_add(1, Ordering::Relaxed);
self.point_full_blob_reads.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_scan_full_blob_read(&self) {
self.full_blob_reads.fetch_add(1, Ordering::Relaxed);
self.scan_full_blob_reads.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_silent_full_blob_read(&self) {
self.full_blob_reads.fetch_add(1, Ordering::Relaxed);
self.silent_full_blob_reads.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_optimistic_restart(&self) {
self.optimistic_restarts.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_range_restart(&self) {
self.range_restarts.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_walker_blob_hops(&self, hops: u64, max_cross_blob_depth: usize) {
self.walker_ops.fetch_add(1, Ordering::Relaxed);
self.walker_blob_hops.fetch_add(hops, Ordering::Relaxed);
fetch_max_relaxed(&self.max_blob_hops, hops);
fetch_max_relaxed(&self.max_cross_blob_depth, max_cross_blob_depth as u64);
}
pub(super) fn note_spillover(&self) {
self.spillover_count.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_merges(&self, merged: u64) {
if merged != 0 {
self.merge_count.fetch_add(merged, Ordering::Relaxed);
}
}
pub(super) fn note_route_resident_demotion(&self) {
self.route_resident_demotions
.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_cache_eviction(&self) {
self.cache_evictions.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_eviction_skip_protected(&self) {
self.eviction_skips_protected
.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_eviction_skip_route_resident(&self) {
self.eviction_skips_route_resident
.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_admission_protect(&self) {
self.admission_protects.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_read_page_hit(&self) {
self.read_page_hits.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_read_page_miss(&self) {
self.read_page_misses.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_read_index_cache_hit(&self) {
self.read_index_cache_hits.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_read_index_cache_miss(&self) {
self.read_index_cache_misses.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_read_index_load(&self, bytes: u64) {
self.read_index_loads.fetch_add(1, Ordering::Relaxed);
self.read_index_dir_read_bytes
.fetch_add(bytes, Ordering::Relaxed);
}
pub(super) fn note_read_index_bucket_read(&self, bytes: u64) {
self.read_index_bucket_reads.fetch_add(1, Ordering::Relaxed);
self.read_index_bucket_read_bytes
.fetch_add(bytes, Ordering::Relaxed);
}
pub(super) fn note_read_index_inline_hit(&self) {
self.read_index_inline_hits.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_read_index_value_hit(&self, bytes: u64) {
self.read_index_value_hits.fetch_add(1, Ordering::Relaxed);
self.read_index_value_read_bytes
.fetch_add(bytes, Ordering::Relaxed);
}
pub(super) fn note_read_index_offset_hit(&self) {
self.read_index_offset_hits.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_read_index_negative_hit(&self) {
self.read_index_negative_hits
.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_read_index_crossing_hit(&self) {
self.read_index_crossing_hits
.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn note_read_index_unknown(&self) {
self.read_index_unknowns.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn cache_hits(&self) -> u64 {
self.cache_hits.load(Ordering::Relaxed)
}
pub(super) fn cache_misses(&self) -> u64 {
self.cache_misses.load(Ordering::Relaxed)
}
pub(super) fn full_blob_reads(&self) -> u64 {
self.full_blob_reads.load(Ordering::Relaxed)
}
pub(super) fn point_full_blob_reads(&self) -> u64 {
self.point_full_blob_reads.load(Ordering::Relaxed)
}
pub(super) fn scan_full_blob_reads(&self) -> u64 {
self.scan_full_blob_reads.load(Ordering::Relaxed)
}
pub(super) fn silent_full_blob_reads(&self) -> u64 {
self.silent_full_blob_reads.load(Ordering::Relaxed)
}
pub(super) fn optimistic_restarts(&self) -> u64 {
self.optimistic_restarts.load(Ordering::Relaxed)
}
pub(super) fn range_restarts(&self) -> u64 {
self.range_restarts.load(Ordering::Relaxed)
}
pub(super) fn walker_ops(&self) -> u64 {
self.walker_ops.load(Ordering::Relaxed)
}
pub(super) fn walker_blob_hops(&self) -> u64 {
self.walker_blob_hops.load(Ordering::Relaxed)
}
pub(super) fn max_blob_hops(&self) -> u64 {
self.max_blob_hops.load(Ordering::Relaxed)
}
pub(super) fn max_cross_blob_depth(&self) -> u64 {
self.max_cross_blob_depth.load(Ordering::Relaxed)
}
pub(super) fn spillover_count(&self) -> u64 {
self.spillover_count.load(Ordering::Relaxed)
}
pub(super) fn merge_count(&self) -> u64 {
self.merge_count.load(Ordering::Relaxed)
}
pub(super) fn route_resident_demotions(&self) -> u64 {
self.route_resident_demotions.load(Ordering::Relaxed)
}
pub(super) fn cache_evictions(&self) -> u64 {
self.cache_evictions.load(Ordering::Relaxed)
}
pub(super) fn eviction_skips_protected(&self) -> u64 {
self.eviction_skips_protected.load(Ordering::Relaxed)
}
pub(super) fn eviction_skips_route_resident(&self) -> u64 {
self.eviction_skips_route_resident.load(Ordering::Relaxed)
}
pub(super) fn admission_protects(&self) -> u64 {
self.admission_protects.load(Ordering::Relaxed)
}
pub(super) fn read_page_hits(&self) -> u64 {
self.read_page_hits.load(Ordering::Relaxed)
}
pub(super) fn read_page_misses(&self) -> u64 {
self.read_page_misses.load(Ordering::Relaxed)
}
pub(super) fn read_index_cache_hits(&self) -> u64 {
self.read_index_cache_hits.load(Ordering::Relaxed)
}
pub(super) fn read_index_cache_misses(&self) -> u64 {
self.read_index_cache_misses.load(Ordering::Relaxed)
}
pub(super) fn read_index_loads(&self) -> u64 {
self.read_index_loads.load(Ordering::Relaxed)
}
pub(super) fn read_index_dir_read_bytes(&self) -> u64 {
self.read_index_dir_read_bytes.load(Ordering::Relaxed)
}
pub(super) fn read_index_bucket_reads(&self) -> u64 {
self.read_index_bucket_reads.load(Ordering::Relaxed)
}
pub(super) fn read_index_bucket_read_bytes(&self) -> u64 {
self.read_index_bucket_read_bytes.load(Ordering::Relaxed)
}
pub(super) fn read_index_inline_hits(&self) -> u64 {
self.read_index_inline_hits.load(Ordering::Relaxed)
}
pub(super) fn read_index_value_hits(&self) -> u64 {
self.read_index_value_hits.load(Ordering::Relaxed)
}
pub(super) fn read_index_value_read_bytes(&self) -> u64 {
self.read_index_value_read_bytes.load(Ordering::Relaxed)
}
pub(super) fn read_index_offset_hits(&self) -> u64 {
self.read_index_offset_hits.load(Ordering::Relaxed)
}
pub(super) fn read_index_negative_hits(&self) -> u64 {
self.read_index_negative_hits.load(Ordering::Relaxed)
}
pub(super) fn read_index_crossing_hits(&self) -> u64 {
self.read_index_crossing_hits.load(Ordering::Relaxed)
}
pub(super) fn read_index_unknowns(&self) -> u64 {
self.read_index_unknowns.load(Ordering::Relaxed)
}
}
#[inline]
fn fetch_max_relaxed(atom: &AtomicU64, value: u64) {
let mut cur = atom.load(Ordering::Relaxed);
while value > cur {
match atom.compare_exchange_weak(cur, value, Ordering::Relaxed, Ordering::Relaxed) {
Ok(_) => break,
Err(actual) => cur = actual,
}
}
}