RadixSpline: Efficient Learned Index
- RadixSpline is a learned index structure that uses piecewise-linear spline interpolation with error-bound guarantees for efficient key lookups.
- It combines a flat radix table for rapid segment localization, optimizing build time, space, and lookup performance compared to traditional methods.
- By tuning the error bound and radix bits, RadixSpline achieves a balanced trade-off between memory usage and latency, benefiting LSM-tree systems and similar applications.
RadixSpline is a learned index structure designed to efficiently approximate position lookups over sorted arrays of key/position pairs. It combines a piecewise-linear, error-bounded spline with a flat radix table for rapid segment localization, providing competitive size and lookup performance compared to state-of-the-art techniques while requiring only a single construction pass and two tunable parameters (Kipf et al., 2020).
1. Formal Description
A RadixSpline index is built over a sorted dataset , where each is a key and its position.
- The spline consists of “knots”: , with strictly increasing and denoting positions.
- interpolates linearly between consecutive knots:
- For every key, , enforcing the error bound .
A flat radix table maps the most significant bits of the keys (with any fixed common prefix removed) to knot intervals:
- For ,
- gives the smallest knot index with 's prefix ,
- is likewise for ,
- localizing to ‥ for subsequent interpolation.
2. One-Pass Construction Algorithm
RadixSpline construction proceeds in a single scan utilizing a Greedy Spline Corridor approach (see I. Apostolico et al.), maintaining error bounds on-the-fly and emitting knots as necessary. The essential steps are:
- Initialize the spline with the first key/position.
- For each subsequent distinct key:
- Update the valid slope corridor constrained by .
- If the corridor is violated, emit the previous key as a new knot.
- After emitting a knot, update the radix table for all newly covered prefixes.
- After processing all keys, emit the final knot and fill any remaining table entries via left-propagation.
- The resulting spline and radix table are output together.
Construction has time complexity—each point is processed once, and both corridor updates and knot emissions are . Space usage is , where under uniform keys.
3. Lookup Procedure and Complexity
Lookup for a query key encompasses three phases:
- Radix localization: Extract prefix ; obtain bracket indices , in knots.
- Knot segment search: Binary search over to find the correct segment for ; perform linear interpolation for a position estimate .
- Final key search: Binary search the original array in for the true lower bound.
The key complexity results are:
- for radix extraction and table lookup.
- on average for segment search ().
- for the final binary search in the error window.
- Worst-case is , with average-case .
4. Parameter Tuning and Trade-Offs
RadixSpline exposes exactly two parameters:
| Parameter | Effect | Trade-off |
|---|---|---|
| (error bound) | Spline fit tightness | Decreasing increases , trading memory for reduced refinement cost. |
| (radix bits) | Radix table granularity | Increasing grows table size and reduces average knot search interval. |
Typical tuning uses so that fits the memory budget for spline points; is then set near , targeting a small knot range per radix slot.
Example for the "face" dataset (M):
- : M, index MiB, minimal latency.
- : M, index MiB, latency 11.5% slower—significantly better space/time trade-off.
As , (degenerating to a full index). As increases, both build time and memory drop, while latency increases modestly.
5. Empirical Evaluation with SOSD Benchmark
RadixSpline has been extensively evaluated in the SOSD setting (AWS c5.4xlarge, 200M 64-bit keys):
Build Time
Lookup Latency
| Index | Lookup (ns/op) |
|---|---|
| BS | 850 |
| B+-tree | 600 |
| ART | 300 |
| RMI | 120–250 |
| RS | 130–280 |
Index Size
- RS is typically 100 MiB on most datasets, but can reach 650 MiB with fine-tuning (, on "face").
- For increasing from , RS memory falls from 650 MiB100 MiB and latency increases from .
LSM-Tree Integration (RocksDB, "osmc" dataset)
Replacing per-SSTable B+-tree by RS (, ) for 400M mixed reads/writes:
- Read latency
- Write latency (single-pass build during compaction)
- Total execution time
- Index memory (allowing larger Bloom filters)
6. Implementation and Optimization Considerations
- RadixSpline is implemented in approximately 100 lines of C++ with no dependencies on external ML libraries.
- Subtracting out any fixed key prefix before radix splitting reduces and the radix table size.
- Store knot key and position arrays contiguously for cache locality.
- can use 32-bit integers (as ).
- The radix table is filled incrementally, left-to-right, as knots are emitted, maximizing memory locality.
- In domains with highly skewed key distributions causing some radix slots to cover many knots, a small auxiliary tree per slot is suggested as a fallback.
- The only essential auxiliary operation is a fast integer binary search.
7. Context and Relationships
RadixSpline directly addresses previously noted shortcomings in learned index construction: multi-pass training requirements and implementation complexity. Compared to recursive model index (RMI) approaches—requiring multiple passes with further learned models—RadixSpline achieves competitive lookup and size metrics with a single pass and no ML library dependencies (Kipf et al., 2020). The theoretical underpinnings rely on the error-bounded Greedy Spline Corridor fitting method (I. Apostolico et al.), ensuring formal guarantees on absolute error and supporting efficient online knot placement.
RadixSpline's empirical and theoretical properties make it suitable for a wide variety of workloads, from raw array indexing to integration in LSM-tree storage engines such as RocksDB, where it delivers quantifiable improvements in both speed and memory efficiency.