Skip to content

Re-express the point-in-area interval index on the shared RTree#441

Closed
asinghvi17 wants to merge 1 commit into
relateng-payload-treefrom
relateng-interval-tree
Closed

Re-express the point-in-area interval index on the shared RTree#441
asinghvi17 wants to merge 1 commit into
relateng-payload-treefrom
relateng-interval-tree

Conversation

@asinghvi17

Copy link
Copy Markdown
Member

Stacked on #440 (base branch relateng-payload-tree) — the last of the three substrate-audit follow-ups.

SortedPackedIntervalRTree was a from-scratch packed tree that duplicated the shared bulk-loading substrate piece by piece: its midpoint sort (JTS NodeComparator) is exactly sort-tile-recursive in one dimension, and its flat per-level min/max arrays are the same bottom-up consecutive-run extent packing. With #440's payload-carrying RTree, the whole thing is expressible as a constructor call: the prepared point-in-area locator's segment index is now

RTree(STR(), segs; extents = y_intervals)   # 1-D (Y,) extents

queried through SpatialTreeInterface.depth_first_search with a closed [y, y] interval extent (the do-block callback form, so the RayCrossingCounter loop stays allocation-free). What's preserved and what changed:

  • The 1-D stabbing contract is unchanged: the horizontal ray must visit every segment whose y-interval contains p.y regardless of x, so a 2-D index could not prune more without changing the ray-counting contract; closed-interval touch semantics match (Extents.intersects is closed).
  • The midpoint-sorted layout is preserved by construction — STR's first (only) dimension sort is the midpoint sort, keeping the measured ~3× query win over ring order for this build-once-query-forever index.
  • The tree shape changes from JTS's binary pairwise packing to the RTree default 16-ary fanout; query results are extent-checked and set-identical (the test suite compares against brute force).
  • IntervalIndexedGeometry.isEmpty becomes index === nothing (an empty polygonal geometry contributes no segments), replacing the separate is_empty flag.

Net: −104 lines (the source file shrinks by ~145), and RelateNG's last private index structure now sits on the shared substrate.

Tests

The SortedPackedIntervalRTree testset is re-expressed as a 1-D stabbing testset over the new index shape (same cases: duplicates, point intervals, closed-interval touches, brute-force sweeps). Green on this branch: indexed point-in-area (incl. the 10k-vertex prepared-vs-unprepared differential), point locator, allocations + type stability, LibGEOS differential fuzz (500).

⚠️ The two long gate files (relate_ng.jl engine, xml_suite.jl JTS conformance) were repeatedly terminated externally while running in the background (the second engine attempt died ~19 min in, likely moments from passing); they passed on the base branch #440 and this branch touches only the prepared locator's index internals, which the fuzz + differential testsets exercise end-to-end. They still need one clean confirmation run before undrafting.

🤖 Generated with Claude Code

`SortedPackedIntervalRTree` was a from-scratch packed tree duplicating
the shared bulk-loading substrate: sort-tile-recursive in one dimension
IS its midpoint sort (JTS `NodeComparator`), and the packed levels are
the same bottom-up extent reduction. The locator's segment index is now
`RTree(STR(), segs; extents = y_intervals)` over 1-D `(Y,)` extents,
queried through `depth_first_search` with a closed-interval extent — the
sound 1-D stabbing contract is unchanged, and the measured sorted-layout
query win is preserved by construction.

`IntervalIndexedGeometry.isEmpty` becomes `index === nothing` (an empty
polygonal geometry contributes no segments), replacing the separate
`is_empty` flag.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@asinghvi17

Copy link
Copy Markdown
Member Author

Collapsed into #416 for whole-piece review — the relateng branch was fast-forwarded to this stack's tip, so #416 now contains these commits. This PR stays as a focused, reviewable diff of its layer (see the review map in #416).

@asinghvi17 asinghvi17 closed this Jul 14, 2026
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