Skip to content

feat(bkd): record per-child AABB on internal nodes and leaf blocks#308

Merged
mosuka merged 1 commit intofeat/bkd-3d-geofrom
feat/bkd-aabb-nodes
Apr 26, 2026
Merged

feat(bkd): record per-child AABB on internal nodes and leaf blocks#308
mosuka merged 1 commit intofeat/bkd-3d-geofrom
feat/bkd-aabb-nodes

Conversation

@mosuka
Copy link
Copy Markdown
Owner

@mosuka mosuka commented Apr 26, 2026

Summary

  • Bump the BKD on-disk format to version 2: every internal index node now stores left_min/left_max/right_min/right_max, and every leaf block stores leaf_min/leaf_max, for all num_dims axes.
  • The writer threads a new SubtreeInfo value up the recursion — leaves contribute their scanned AABB, internal nodes union their children's — and back-patches the AABBs onto each IndexNode slot.
  • node_size is now a helper that knows the dimensionality-dependent size (28 + 32 * num_dims bytes), used in both the root-offset calculation and the index serialization loop.
  • Reader changes are intentionally minimal: BKDReader::open rejects any version != 2 (no V1 dual-support, since laurus is pre-release), and visit_node / visit_leaf_block consume the new AABB bytes so the on-disk offsets stay aligned.

Why

Per the parent issue #289, recording AABBs on every node is the prerequisite for the Inside/Outside/Crosses pruning that #292 will introduce via IntersectVisitor. Without per-node AABBs, 3D distance / sphere queries would degenerate to per-leaf full scans.

Out of scope

Test plan

  • cargo test -p laurus — 704 lib tests + all integration tests pass (was 701; +3 new BKD tests).
  • cargo clippy -p laurus --tests -- -D warnings — no warnings.
  • cargo fmt --check — pass.
  • New tests: 3D multi-block round-trip, 2D single-leaf round-trip (leaf-only path), explicit rejection of a hand-crafted V1 header.

Refs #289
Closes #291

Bump the BKD on-disk format to version 2 so every internal index node
carries left_min/left_max/right_min/right_max and every leaf block
carries leaf_min/leaf_max for all `num_dims` axes.

The writer threads a `SubtreeInfo` up the recursion: leaves contribute
their scanned AABB, internal nodes union their children's. The new
metadata is materialized in both the leaf bytes and the index section,
and `node_size` is now a helper that knows the dimensionality-dependent
size (28 + 32 * num_dims bytes).

Reader changes are minimal in this PR: BKDReader::open rejects any
version != 2 (no V1 dual-support since laurus is pre-release), and
visit_node / visit_leaf_block consume the new AABB bytes without yet
using them for pruning. Inside/Outside/Crosses pruning lands in #292
when IntersectVisitor is introduced.

Tests cover a 3D multi-block round-trip, a 2D single-leaf round-trip,
and explicit rejection of a hand-crafted V1 header.

Refs #289
Closes #291
@mosuka mosuka merged commit e5c42c2 into feat/bkd-3d-geo Apr 26, 2026
1 check passed
@mosuka mosuka deleted the feat/bkd-aabb-nodes branch April 26, 2026 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant