solana/runtime/src/bucket_map_holder_stats.rs

194 lines
6.1 KiB
Rust
Raw Normal View History

2021-09-20 12:30:12 -07:00
use crate::accounts_index::IndexValue;
use crate::bucket_map_holder::BucketMapHolder;
use solana_sdk::timing::{timestamp, AtomicInterval};
2021-09-12 15:14:59 -07:00
use std::fmt::Debug;
2021-09-20 12:30:12 -07:00
use std::sync::atomic::{AtomicU64, AtomicU8, Ordering};
use std::sync::Arc;
2021-09-12 15:14:59 -07:00
#[derive(Debug, Default)]
pub struct BucketMapHolderStats {
pub get_mem_us: AtomicU64,
pub gets_from_mem: AtomicU64,
pub get_missing_us: AtomicU64,
pub gets_missing: AtomicU64,
pub entry_mem_us: AtomicU64,
pub entries_from_mem: AtomicU64,
pub entry_missing_us: AtomicU64,
pub entries_missing: AtomicU64,
pub updates_in_mem: AtomicU64,
2021-09-12 15:14:59 -07:00
pub items: AtomicU64,
pub keys: AtomicU64,
pub deletes: AtomicU64,
pub inserts: AtomicU64,
2021-09-13 17:26:49 -07:00
pub count_in_mem: AtomicU64,
pub per_bucket_count: Vec<AtomicU64>,
pub flush_entries_updated_on_disk: AtomicU64,
pub active_threads: AtomicU64,
2021-09-17 15:19:29 -07:00
pub get_range_us: AtomicU64,
2021-09-20 12:30:12 -07:00
last_age: AtomicU8,
last_age_time: AtomicU64,
pub flush_scan_us: AtomicU64,
pub flush_update_us: AtomicU64,
pub flush_remove_us: AtomicU64,
last_time: AtomicInterval,
2021-09-12 15:14:59 -07:00
}
impl BucketMapHolderStats {
2021-09-13 17:26:49 -07:00
pub fn new(bins: usize) -> BucketMapHolderStats {
BucketMapHolderStats {
per_bucket_count: (0..bins)
.into_iter()
.map(|_| AtomicU64::default())
.collect(),
..BucketMapHolderStats::default()
}
}
pub fn insert_or_delete(&self, insert: bool, bin: usize) {
let per_bucket = self.per_bucket_count.get(bin);
if insert {
self.inserts.fetch_add(1, Ordering::Relaxed);
self.count_in_mem.fetch_add(1, Ordering::Relaxed);
per_bucket.map(|count| count.fetch_add(1, Ordering::Relaxed));
} else {
self.deletes.fetch_add(1, Ordering::Relaxed);
self.count_in_mem.fetch_sub(1, Ordering::Relaxed);
per_bucket.map(|count| count.fetch_sub(1, Ordering::Relaxed));
}
}
2021-09-20 12:30:12 -07:00
pub fn get_elapsed_ms_and_reset(&self) -> u64 {
let now = timestamp();
let last = self.last_age_time.swap(now, Ordering::Relaxed);
now.saturating_sub(last) // could saturate to 0. That is ok.
}
fn ms_per_age<T: IndexValue>(&self, storage: &Arc<BucketMapHolder<T>>) -> u64 {
let elapsed_ms = self.get_elapsed_ms_and_reset();
let mut age_now = storage.current_age();
let last_age = self.last_age.swap(age_now, Ordering::Relaxed);
if last_age > age_now {
// age may have wrapped
age_now += u8::MAX;
}
let age_delta = age_now.saturating_sub(last_age) as u64;
if age_delta > 0 {
elapsed_ms / age_delta
} else {
0
}
}
pub fn report_stats<T: IndexValue>(&self, storage: &Arc<BucketMapHolder<T>>) {
// account index stats every 10 s
if !self.last_time.should_update(10_000) {
return;
}
2021-09-20 12:30:12 -07:00
let ms_per_age = self.ms_per_age(storage);
2021-09-13 17:26:49 -07:00
let mut ct = 0;
let mut min = usize::MAX;
let mut max = 0;
for d in &self.per_bucket_count {
let d = d.load(Ordering::Relaxed) as usize;
ct += d;
min = std::cmp::min(min, d);
max = std::cmp::max(max, d);
}
2021-09-12 15:14:59 -07:00
datapoint_info!(
"accounts_index",
2021-09-13 17:26:49 -07:00
(
"count_in_mem",
self.count_in_mem.load(Ordering::Relaxed),
i64
),
("min_in_bin", min, i64),
("max_in_bin", max, i64),
("count_from_bins", ct, i64),
2021-09-12 15:14:59 -07:00
(
"gets_from_mem",
self.gets_from_mem.swap(0, Ordering::Relaxed),
i64
),
(
"get_mem_us",
self.get_mem_us.swap(0, Ordering::Relaxed) / 1000,
i64
),
(
"gets_missing",
self.gets_missing.swap(0, Ordering::Relaxed),
i64
),
(
"get_missing_us",
self.get_missing_us.swap(0, Ordering::Relaxed) / 1000,
i64
),
(
"entries_from_mem",
self.entries_from_mem.swap(0, Ordering::Relaxed),
i64
),
(
"entry_mem_us",
self.entry_mem_us.swap(0, Ordering::Relaxed) / 1000,
i64
),
(
"entries_missing",
self.entries_missing.swap(0, Ordering::Relaxed),
i64
),
(
"entry_missing_us",
self.entry_missing_us.swap(0, Ordering::Relaxed) / 1000,
i64
),
(
"updates_in_mem",
self.updates_in_mem.swap(0, Ordering::Relaxed),
i64
),
2021-09-17 15:19:29 -07:00
(
"get_range_us",
self.get_range_us.swap(0, Ordering::Relaxed),
i64
),
("inserts", self.inserts.swap(0, Ordering::Relaxed), i64),
2021-09-12 15:14:59 -07:00
("deletes", self.deletes.swap(0, Ordering::Relaxed), i64),
(
"active_threads",
self.active_threads.load(Ordering::Relaxed),
i64
),
2021-09-12 15:14:59 -07:00
("items", self.items.swap(0, Ordering::Relaxed), i64),
("keys", self.keys.swap(0, Ordering::Relaxed), i64),
2021-09-20 12:30:12 -07:00
("ms_per_age", ms_per_age, i64),
(
"flush_scan_us",
self.flush_scan_us.swap(0, Ordering::Relaxed),
i64
),
(
"flush_update_us",
self.flush_update_us.swap(0, Ordering::Relaxed),
i64
),
(
"flush_remove_us",
self.flush_remove_us.swap(0, Ordering::Relaxed),
i64
),
(
"flush_entries_updated_on_disk",
self.flush_entries_updated_on_disk
.swap(0, Ordering::Relaxed),
i64
),
2021-09-12 15:14:59 -07:00
);
}
}