Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,13 @@ flatbuffers = "25.2.10"
fsst-rs = "0.6.0"
futures = { version = "0.3.31", default-features = false }
fuzzy-matcher = "0.3"
geo = "0.31.0"
# `vortex-spatial`'s `contains_route` transcribes geo's `impl_contains_from_relate!` dispatch
# table, so any bump that moves a row silently changes containment verdicts. The tests stay green
# wherever relate and the direct algorithm agree. Pinned exactly so that taking any new geo,
# patch releases included, is a deliberate edit of this line that re-verifies the table; a caret
# requirement would let `cargo update` (or automated lockfile maintenance) take 0.31.x with no diff
# to review. See `vortex-spatial/src/scalar_fn/contains.rs`.
geo = "=0.31.0"
geo-traits = "0.3.0"
geo-types = "0.7.19"
geoarrow = "0.8.0"
Expand Down
26 changes: 21 additions & 5 deletions vortex-spatial/benches/binary_predicates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@
//! column-x-column arms are the control: no operand is constant, so a prepared path has nothing to
//! hoist and must not regress them.
//!
//! `contains` has no all-overlapping arm. One `contains(query polygon, contained square)` row
//! builds a topology graph over the constant's 128 edges, which CodSpeed's CPU simulation charges
//! around 120 µs, so no row count both fits the per-iteration budget and exercises the row loop.
//! [`intersects::polygons_overlapping_x_constant`] covers the never-rejects case instead.
//!
//! Run with `cargo bench -p vortex-spatial --bench binary_predicates`.

#![expect(clippy::unwrap_used)]
Expand Down Expand Up @@ -64,6 +59,10 @@ const ROWS: usize = 1 << 7;
/// pairwise predicate. It needs a smaller fixture than [`ROWS`] to stay inside the same budget.
const OVERLAPPING_POLYGON_ROWS: usize = 1 << 5;

/// Containment builds a topology graph for each polygon pair. Four rows fit the benchmark budget
/// while exercising construction followed by reuse of the prepared constant geometry.
const CONTAINED_POLYGON_ROWS: usize = 4;

/// Deterministic pseudo-random value in `[0, 1)`.
fn unit(i: usize) -> f64 {
((i.wrapping_mul(2654435761) >> 8) % 10_000) as f64 / 10_000.0
Expand Down Expand Up @@ -225,6 +224,23 @@ mod contains {
});
}

/// Constant container against contained polygons: every bbox check passes, the first row
/// prepares the constant geometry, and the remaining rows reuse it for the full predicate.
#[divan::bench]
fn constant_x_polygons_overlapping(bencher: Bencher) {
let mut ctx = SESSION.create_execution_ctx();
let query = query_constant(&mut ctx, CONTAINED_POLYGON_ROWS);
let polygons = squares_mostly_overlapping(CONTAINED_POLYGON_ROWS);
bencher
.counter(ItemsCount::new(CONTAINED_POLYGON_ROWS))
.bench_local(|| {
execute(
SpatialContains::try_new_array(query.clone(), polygons.clone()),
&mut ctx,
)
});
}

/// Constant container against a point column with one null row in eight.
#[divan::bench]
fn constant_x_nullable_points(bencher: Bencher) {
Expand Down
Loading
Loading