Skip to main content

rudb_kernels/
lib.rs

1//! The compute kernels: casting, comparison, arithmetic, three-valued logic and the aggregates.
2//!
3//! Rank 3 in the layer rule. See `xtask/layers.toml` and `spec/18-package-layout.md`.
4//!
5//! Everything here takes vectors and values and knows nothing about plans, operators or catalogs.
6//! That is what makes it callable from the interpreter, from the fused kernels of tier 1 and from
7//! a test that wants to check one conversion, and it is why the comparison enum in [`Comparison`] is
8//! this crate's own rather than the plan's.
9//!
10//! # What tier this is
11//!
12//! `spec/08-codegen.md` section 8.1 puts four tiers on the table and says tier 0 is never optional,
13//! because it is the reference every faster tier is differentially tested against. This crate is
14//! the compute half of tier 0.
15//!
16//! Every kernel here takes a vector and produces a vector, and the body of every one of them is a
17//! scalar loop over [`rudb_vector::Vector::value_at`]. That is slow, it is slow on purpose, and it
18//! is slow in a way that is visible: the interface is already the batch interface, so a generated
19//! specialization that reads a `&[i32]` out of a flat vector replaces a body without touching a
20//! caller. Section 7.3's kernel generator is what fills those in, and it is M1 work rather than M0
21//! work because there is no benchmark to aim it at until there is an executor to run one.
22//!
23//! The one optimization that is here is the constant fast path: a cast or a comparison where both
24//! sides are constant vectors costs one operation rather than 1024. That one is worth having now
25//! because the binder turns every literal in a predicate into a constant vector, so it is on the
26//! path of the first query anybody runs.
27//!
28//! # What is not here
29//!
30//! Encoded and dictionary specialization, which is M3. SIMD, which is M1 and which the generator
31//! produces rather than a person writing it. Regular expressions, dates arithmetic, the string
32//! functions past the four here, and the statistical aggregates. Each of those is a signature in
33//! `rudb-functions` before it is a kernel here, so the missing ones fail at binding with a message
34//! naming the function rather than here with a message naming a match arm.
35
36#![forbid(unsafe_code)]
37
38pub mod aggregate;
39pub mod cast;
40pub mod compare;
41pub mod logic;
42mod number;
43pub mod scalar;
44
45pub use aggregate::Accumulator;
46pub use cast::{cast, cast_value};
47pub use compare::{Comparison, compare, compare_values, order, order_with_nulls};
48pub use logic::{Connective, combine, is_true};
49pub use scalar::{call, call_values};