Carry payloads in RTree and dissolve the relate edge-index side-tables#440
Closed
asinghvi17 wants to merge 2 commits into
Closed
Carry payloads in RTree and dissolve the relate edge-index side-tables#440asinghvi17 wants to merge 2 commits into
RTree and dissolve the relate edge-index side-tables#440asinghvi17 wants to merge 2 commits into
Conversation
Queries return indices into the input collection, but the tree previously threw the collection away — every consumer had to carry a parallel payload vector alongside the tree. Keep it as `tree.data` instead, and accept an `extents` vector for payload elements that carry no extent of their own (or extents computed in another coordinate space). `Unsorted` loading now returns `Base.OneTo` from `loadorder`, so the constructor skips the identity permutation and aliases the extents vector as the leaf level — zero copies, matching `NaturalIndex`'s build cost. `RTreeNode` is reparametrized on the concrete tree type since `RTree` gained type parameters. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`_relate_edge_index(m, ss_list)` now returns a natural-order `RTree` whose data is the (string index, segment index) owner of each leaf, built directly from the flattened segment extents. This replaces the `NaturalIndex` + parallel `owners` vector at the three dual-traversal sites, and `PreparedEdgeIndex` — a pair of exactly those two — dissolves into the tree itself (`PreparedRelate.edge_tree` is now the `RTree` or `nothing`). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 13, 2026
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #439 (base branch
relateng-cleanups). The "payload-carrying tree" follow-up from the substrate audit, in two commits.RTreecarries the collection it indexes. Queries already return indices into the input collection, but the tree threw the collection away — so every consumer had to carry a parallel payload vector alongside the tree (JTS trees carry their items; the index-returning design needs the vector to live somewhere). It now lives on the tree astree.data. Two supporting changes:extentskwarg supplies precomputed extents (one per element, in order) for payload elements that carry no extent of their own, or extents computed in another coordinate space — the relate kernel computes segment extents over kernel-converted points, whichGI.extenton the payload could never reproduce.Unsortedloading returnsBase.OneTofromloadorder, so the constructor skips the identity permutation and aliases the extents vector as the leaf level. Zero copies — the same build cost asNaturalIndex, makingRTree(Unsorted(), ...)a true natural index. (RTreeNodeis reparametrized on the concrete tree type sinceRTreegained type parameters.)The relate edge index dissolves its side-tables.
_relate_edge_index(m, ss_list)now returns a natural-orderRTreewhose data is each leaf's (string index, segment index) owner, built from the flattened segment extents (ornothingfor empty lists). The three dual-traversal sites map hits throughtree.data[i]instead of a parallelownersvector, andPreparedEdgeIndex— a struct pairing exactly that tree with exactly that vector — dissolves into the tree itself:PreparedRelate.edge_treeis now theRTreeornothing.This sets up the interval-tree follow-up:
SortedPackedIntervalRTreeis a midpoint-sorted packed tree over 1-D intervals carrying segment payloads, which isRTree(STR(), segs; extents = y_intervals)— STR in one dimension is the midpoint sort.Tests
New
FlexibleRTreestestset covers payload round-trips under reordering, theUnsortedzero-copy aliasing, collected non-vector input, and the extents/data length mismatch throw; the existing brute-force query sweeps now exercise the zero-copyUnsortedpath. RelateNG: engine + prepared mode, edge intersector accelerator differentials, spherical end-to-end, JTS XML conformance, LibGEOS fuzz, and the allocation budget (256-vertex pairs exceed the tree threshold, so the budget covers the new build path) all green.🤖 Generated with Claude Code