Skip to main content

keep

Function keep 

Source
fn keep<T: Copy>(
    sel: &mut Vec<u32>,
    nulls: Option<&NullBuffer>,
    vals: &[T],
    p: impl Fn(T) -> bool,
)
Expand description

Narrow sel to the rows where p(vals[row]) holds.

Three shapes, because the first one is the whole point. A column with no nulls, not yet narrowed by an earlier term — which is every first term on a block the time range covers whole — walks vals contiguously and writes the surviving row number unconditionally, advancing the cursor by the boolean. No indirect call, no bounds check on the load, and no branch in the body, so the comparison itself stays in vector registers.

sel.len() == vals.len() is what proves the selection is still the identity 0..n: Block::select only ever removes from it, and it is built ascending, so a full-length selection has nothing missing from it.

ponytail: the two narrowed shapes stay a gather under retain and do not vectorise. Making them would mean the selection becoming a bitmap so every term reads and writes contiguously — a different engine, and worth it only once a query with several selective terms shows up in a profile. Terms are applied cheapest-first-by-accident today, and most queries carry one.