Skip to content

Add FlexibleRTrees and speed up NaturalIndex traversal#431

Merged
asinghvi17 merged 4 commits into
mainfrom
tree-improvements
Jul 6, 2026
Merged

Add FlexibleRTrees and speed up NaturalIndex traversal#431
asinghvi17 merged 4 commits into
mainfrom
tree-improvements

Conversation

@asinghvi17

@asinghvi17 asinghvi17 commented Jul 6, 2026

Copy link
Copy Markdown
Member

Split out of #428 so the spatial-tree improvements can land independently of prepared geometry.

FlexibleRTrees (new)

A packed , static R-tree over Extents of any dimensionality, vendored and restructured from SortTileRecursiveTree.jl. Storage is a flat vector of per-level extent vectors plus a leaf permutation (like NaturalIndex and JTS HPRtree), so RTree{A, E} is concrete regardless of depth and fully inferrable.

Benchmarks: on spatially random collections, HPR beats STR by ~20% and unsorted packing by ~1000×; on ring edges natural order remains fastest, confirming NaturalIndex as the default there. The other advantage here is type stability, so you can do things like nearest neighbour queries and distance queries on it.

NaturalIndex traversal speed-up

Each per-child operation (nchild, getchild, child_indices_extents) re-chased parent_index → levels → level → extents for every child, and profiles showed that pointer chase dominating tree-query time. Hoisting the child-extent vector once per node makes generic SpatialTreeInterface queries ~1.7× faster (point-in-polygon over an indexed ring: 300 ns → 178 ns per query on a 65k-vertex polygon) with no interface or layout change.

Relation to #428

The prepared-geometry integration stays there: the build_edge_tree hook that lets a bulk-load algorithm select RTree as an edge-tree backend, and the corresponding integration testset.

🤖 Generated with Claude Code

asinghvi17 and others added 2 commits July 6, 2026 09:47
…le bulk loading

Vendored and restructured from SortTileRecursiveTree.jl: storage is a flat
vector of per-level extent vectors plus a leaf permutation (like
`NaturalIndex` and JTS `HPRtree`), so `RTree{A, E}` is concrete regardless of
depth, works for extents of any dimensionality, and is fully inferrable. The
bulk-load algorithm is a value — `RTree(STR() | HPR() | Unsorted(), data)` —
where `HPR` sorts by Skilling N-dimensional Hilbert codes and adding an
algorithm is one singleton type plus one `loadorder` method. Implements
SpatialTreeInterface, so `depth_first_search` and everything built on it
work unchanged.

Benchmarks: on spatially random collections HPR beats STR by ~20% and
unsorted packing by ~1000x; on ring edges natural order remains fastest,
confirming `NaturalIndex` as the default there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Each per-child operation (`nchild`, `getchild`, `child_indices_extents`)
re-chased `parent_index -> levels -> level -> extents` for every child, and
profiles showed that pointer chase dominating tree-query time. Hoisting the
child-extent vector once per node makes the generic SpatialTreeInterface
queries ~1.7x faster (point-in-polygon over an indexed ring: 300 ns -> 178 ns
per query on a 65k-vertex polygon) with no interface or layout change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread src/utils/FlexibleRTrees/FlexibleRTrees.jl Outdated
asinghvi17 and others added 2 commits July 6, 2026 10:01
Split the module body into one file per concern, following the
SpatialTreeInterface convention: `types.jl` (the `BulkLoadAlgorithm`s and
`RTree`), `bulk_loading.jl` (`loadorder` methods and packing),
`interface.jl` (SpatialTreeInterface implementation and `query`), with
`hilbert.jl` unchanged. Pure code motion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
They sit with the file that extends them; drops the `node_extent` import,
which nothing extended or called.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@asinghvi17 asinghvi17 merged commit f57277b into main Jul 6, 2026
7 checks passed
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