Cost Model & Index Selection
Index types
PyCanopy chooses among four spatial access paths:
| Index | Best for |
|---|---|
| KD-tree | Point kNN and range queries over clustered point data |
| R-tree | Polygon queries and bounding-box searches |
| Grid | Range and distance queries over uniformly distributed points |
| Brute force | Small datasets or queries expected to scan or return much of the dataset |
Index mode
index_mode is set on SpatialFrame construction and can later be changed through
sf.engine.set_index_mode(...).
| Mode | Behavior |
|---|---|
auto (default) |
Build index only when the cost model says it beats a scan |
eager |
Use the rule-selected access path without comparing its estimated cost with a scan |
none |
Always scan brute-force |
Candidate index selection
When the engine considers building a new index, select_index applies these rules to pick
the candidate type:
flowchart TD
A[Query arrives] --> B{N < 500\nor sel > 50%?}
B -- yes --> BF[Brute force]
B -- no --> C{kNN with\nk/N > 10%?}
C -- yes --> BF
C -- no --> D{Polygon\ndataset?}
D -- yes --> RT[R-tree]
D -- no --> E{Range query\nand uniform?}
E -- yes --> GR[Grid]
E -- no --> KD[KD-tree]
Point distribution is classified from variation in grid-cell counts. A separate 32×32 histogram estimates range selectivity; polygon histograms count exterior-ring centroids.
In auto mode, cached indexes are also candidates and their build cost is already paid.
Cost gate
When index_mode="auto", the planner compares the applicable costs and picks the minimum
(\(Q\) = probe count, \(N\) = dataset size):
Selectivity (fraction of \(N\) expected to match):
Probe cost (\(Q\) warm queries against a built index):
Build cost (paid once and compared with the probe cost for all \(Q\) queries):
Calibration
The formulas above use generic names for readability. The operation-specific constants in
src/planner/calibration.rs can be recalibrated with:
uv run python -m bench.ops
# Optional timing repetitions and random seed
uv run python -m bench.ops --runs 5 --seed 42
The suite normalizes timings across point and polygon dataset sizes and reports the median ratio. Use a release build when calibrating for target hardware.