#![allow(unsafe_code)]
use crate::engine::CostEstimate;
use crate::panic_guard::FfiBoundary;
use crate::runtime::EngineContext;
fn report_cost(
io: *mut f64,
cpu: *mut f64,
import: *mut f64,
mem: *mut f64,
value: Option<CostEstimate>,
) -> bool {
match value {
Some(c) => {
unsafe {
if !io.is_null() {
*io = c.io_cost();
}
if !cpu.is_null() {
*cpu = c.cpu_cost();
}
if !import.is_null() {
*import = c.import_cost();
}
if !mem.is_null() {
*mem = c.mem_cost();
}
}
true
}
None => false,
}
}
#[doc(hidden)]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__handler__table_scan_cost(
ctx: *mut EngineContext,
io: *mut f64,
cpu: *mut f64,
import: *mut f64,
mem: *mut f64,
) -> bool {
FfiBoundary::run_default(false, || {
let value = unsafe { &mut *ctx }.engine_mut().table_scan_cost();
report_cost(io, cpu, import, mem, value)
})
}
#[doc(hidden)]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__handler__index_scan_cost(
ctx: *mut EngineContext,
index: u32,
ranges: f64,
rows: f64,
io: *mut f64,
cpu: *mut f64,
import: *mut f64,
mem: *mut f64,
) -> bool {
FfiBoundary::run_default(false, || {
let value = unsafe { &mut *ctx }
.engine_mut()
.index_scan_cost(index, ranges, rows);
report_cost(io, cpu, import, mem, value)
})
}
#[doc(hidden)]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rust__handler__read_cost(
ctx: *mut EngineContext,
index: u32,
ranges: f64,
rows: f64,
io: *mut f64,
cpu: *mut f64,
import: *mut f64,
mem: *mut f64,
) -> bool {
FfiBoundary::run_default(false, || {
let value = unsafe { &mut *ctx }
.engine_mut()
.read_cost(index, ranges, rows);
report_cost(io, cpu, import, mem, value)
})
}
#[cfg(test)]
mod tests {
use super::report_cost;
use crate::engine::CostEstimate;
#[test]
fn report_cost_writes_components_and_signals_handled() {
let (mut io, mut cpu, mut import, mut mem) = (0.0, 0.0, 0.0, 0.0);
let handled = report_cost(
&raw mut io,
&raw mut cpu,
&raw mut import,
&raw mut mem,
Some(CostEstimate::new(1.0, 2.0, 3.0, 4.0)),
);
assert!(handled);
assert_eq!((io, cpu, import, mem), (1.0, 2.0, 3.0, 4.0));
}
#[test]
fn report_cost_none_leaves_buffers_and_signals_unhandled() {
let (mut io, mut cpu, mut import, mut mem) = (9.0, 9.0, 9.0, 9.0);
let handled = report_cost(
&raw mut io,
&raw mut cpu,
&raw mut import,
&raw mut mem,
None,
);
assert!(!handled);
assert_eq!((io, cpu, import, mem), (9.0, 9.0, 9.0, 9.0));
}
#[test]
fn report_cost_tolerates_null_out_pointers() {
let null = core::ptr::null_mut();
assert!(report_cost(
null,
null,
null,
null,
Some(CostEstimate::new(1.0, 2.0, 3.0, 4.0)),
));
}
}