use std::sync::atomic::{AtomicU64, Ordering};
use rudb_vector::Form;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Kernel {
Compare,
Scalar,
Logic,
Cast,
Aggregate,
Select,
}
impl Kernel {
const ALL: [Self; 6] =
[Self::Compare, Self::Scalar, Self::Logic, Self::Cast, Self::Aggregate, Self::Select];
#[must_use]
pub fn name(self) -> &'static str {
match self {
Self::Compare => "compare",
Self::Scalar => "scalar",
Self::Logic => "logic",
Self::Cast => "cast",
Self::Aggregate => "aggregate",
Self::Select => "select",
}
}
fn index(self) -> usize {
match self {
Self::Compare => 0,
Self::Scalar => 1,
Self::Logic => 2,
Self::Cast => 3,
Self::Aggregate => 4,
Self::Select => 5,
}
}
}
const FORMS: [Form; 4] = [Form::Flat, Form::Constant, Form::Sequence, Form::Dictionary];
fn form_name(form: Form) -> &'static str {
match form {
Form::Flat => "flat",
Form::Constant => "constant",
Form::Sequence => "sequence",
Form::Dictionary => "dictionary",
_ => "other",
}
}
fn form_index(form: Form) -> usize {
FORMS.iter().position(|&known| known == form).unwrap_or(FORMS.len())
}
const WIDTH: usize = FORMS.len() + 1;
const CELLS: usize = Kernel::ALL.len() * WIDTH * WIDTH;
static COUNTS: [AtomicU64; CELLS] = [const { AtomicU64::new(0) }; CELLS];
fn cell(kernel: Kernel, left: Form, right: Form) -> usize {
kernel.index() * WIDTH * WIDTH + form_index(left) * WIDTH + form_index(right)
}
pub fn record(kernel: Kernel, left: Form, right: Form) {
COUNTS[cell(kernel, left, right)].fetch_add(1, Ordering::Relaxed);
}
#[must_use]
pub fn count(kernel: Kernel, left: Form, right: Form) -> u64 {
COUNTS[cell(kernel, left, right)].load(Ordering::Relaxed)
}
#[must_use]
pub fn hot() -> Vec<(Kernel, Form, Form, u64)> {
let mut out = Vec::new();
for kernel in Kernel::ALL {
for left in FORMS {
for right in FORMS {
let seen = count(kernel, left, right);
if seen > 0 {
out.push((kernel, left, right, seen));
}
}
}
}
out.sort_by_key(|entry| std::cmp::Reverse(entry.3));
out
}
pub fn reset() {
for counter in &COUNTS {
counter.store(0, Ordering::Relaxed);
}
}
#[cfg(test)]
pub(crate) static TURN: std::sync::Mutex<()> = std::sync::Mutex::new(());
#[must_use]
pub fn report() -> String {
let hot = hot();
if hot.is_empty() {
return "every kernel call took a specialized path".to_owned();
}
let mut out = String::from("kernel calls that fell through to the row at a time path\n");
for (kernel, left, right, seen) in hot {
out.push_str(&format!(
" {:<10} {:<10} against {:<10} {seen}\n",
kernel.name(),
form_name(left),
form_name(right)
));
}
out
}
#[cfg(test)]
mod tests {
use super::{Form, Kernel, TURN, count, hot, record, report, reset};
#[test]
fn a_fall_through_lands_in_the_cell_for_its_own_form_pair() {
let _turn = TURN.lock().expect("no test panics while holding this");
reset();
record(Kernel::Compare, Form::Sequence, Form::Constant);
record(Kernel::Compare, Form::Sequence, Form::Constant);
record(Kernel::Cast, Form::Dictionary, Form::Flat);
assert_eq!(count(Kernel::Compare, Form::Sequence, Form::Constant), 2);
assert_eq!(count(Kernel::Cast, Form::Dictionary, Form::Flat), 1);
assert_eq!(count(Kernel::Compare, Form::Constant, Form::Sequence), 0);
assert_eq!(count(Kernel::Compare, Form::Flat, Form::Flat), 0);
reset();
}
#[test]
fn the_report_names_the_combination_rather_than_a_number_on_its_own() {
let _turn = TURN.lock().expect("no test panics while holding this");
reset();
assert!(report().contains("every kernel call took a specialized path"));
for _ in 0..7 {
record(Kernel::Compare, Form::Sequence, Form::Constant);
}
record(Kernel::Logic, Form::Flat, Form::Dictionary);
let text = report();
assert!(text.contains("compare"), "{text}");
assert!(text.contains("sequence"), "{text}");
assert!(text.contains('7'), "{text}");
assert_eq!(hot().first().map(|entry| entry.3), Some(7));
reset();
}
}