Adaptive radix trees: compress shared paths, adapt the branches
Explain bytewise trie navigation, path compression, adaptive node layouts, and the encoding needed to preserve database ordering.
On this page
The question for today
What you’ll understand
- Distinguish path compression from adapting node capacity.
- Explain the original ART node families without treating one layout as a universal implementation.
- Account for key encoding, full-key validation, and memory-access costs.
A radix tree navigates pieces of a key rather than repeatedly comparing the entire key against separators. Shared prefixes become shared paths. The adaptive radix tree combines that idea with node layouts sized for different branch counts, aiming to avoid paying for a large sparse child array at every step. Its benefits depend on key representation and actual memory behavior.
A compressed path represents skipped key material
In a bytewise trie, an internal branch selects the next key byte. Several keys beginning with the same bytes follow the same path until they differ. Path compression replaces a chain with only one meaningful child at each step by a stored prefix and a later branch. Lookup must still establish that the compressed prefix matches the query; removing intermediate nodes does not authorize ignoring their bytes. Leaf validation may compare a complete key, especially in implementations that store only part of a long compressed prefix directly in the node.
Variable-length keys need an unambiguous way to distinguish a key from its extension, such as an appropriate terminal representation. The strings a and ab must not become indistinguishable when the first ends. Bytewise order also needs to match the intended database comparison. Unsigned fixed-width integers can use an order-preserving big-endian representation, but signed integers, floating-point values, and collated text require additional rules. Raw UTF-8 byte order is not a universal replacement for a database collation, and equality semantics must remain consistent with lookup.
Adaptive layouts reduce sparse child-array costs
The original ART design uses Node4, Node16, Node48, and Node256 families to accommodate different numbers of byte-labeled children. Small nodes store compact key-byte and child arrays. A Node48 uses a byte-indexed mapping into a smaller child-reference array; a Node256 can directly index a child array by byte. Those choices trade selection work and metadata against unused pointer slots. They are specific published design mechanisms, not a claim that every structure called a radix tree has those names or exact machine-byte sizes.
When a node outgrows its representation, insertion can allocate a larger layout and preserve its child mapping; deletion may permit shrinking under the implementation's policy. Path compression and node adaptation solve separate problems: one reduces unary path overhead, while the other handles branching density. Their interaction with concurrent readers needs publication and reclamation rules beyond the sequential layout. Memory measured per key includes leaves and key storage as well as internal nodes, so counting only the smallest internal representation can dramatically understate the footprint.
Compare mechanisms under an equal workload
A radix structure can support ordered traversal only if its encoding and child iteration preserve the desired order. Hash tables answer a different navigation question, while B-trees group entries into pages with different fanout and cache properties. Compare the same key types, distributions, update ratios, and range requests. Long common prefixes can save node material while still requiring byte comparisons. Very short keys may make other overhead dominant. A benchmark result for one in-memory structure and machine does not establish a universal winner for persistent or concurrent databases.
The cache lab isolates a tiny working-set effect. Reset, set C=2 and s=8, predict two misses and fourteen hits among the sixteen initial requests, then Play or Step. Separately Reset, set C=2 and s=4, predict zero hits for a four-address cycle, then Play or Step. These capacity values count toy addresses, not ART node bytes. The instrument cannot compress prefixes or switch node families. Use it to motivate measuring whether a compact representation actually reduces the active address working set, then perform the separate encoding and full-key correctness checks.
Work it through
Factor a shared prefix without hiding overhead
Four keys are /org/17/a, /org/17/b, /org/17/c, and /org/17/d. Consider a conceptual representation storing their eight-byte shared prefix once and each one-byte suffix separately.
Each complete key has nine bytes, so four independent raw key strings contain 4×9=36 bytes before terminators and object overhead.
Factoring the eight-byte prefix gives 8+4×1=12 key bytes. The conceptual prefix-byte saving is 36−12=24 bytes, matching (4−1)×8.
A real trie still needs branch labels, child references, terminal handling, metadata, and full-key or prefix validation. The 24-byte calculation is not its total memory saving, nor a prediction of lookup latency.
Prefix sharing can remove repeated key material, while adaptive node layouts address a different source of sparse-branch overhead.
The living notebook
Explore the model
Interactive lab · cache
A smaller active address set can fit
Reset, set C=2 and s=8, predict 14 initial hits in 16 requests, then Play or Step. Separately Reset, set C=2 and s=4, predict zero hits, then Play or Step. This deterministic LRU comparison cannot compress a key or instantiate ART nodes; addresses are only a working-set analogy.
- Hits / requests
- 0 / 16
- Hit rate
- 0%
- Address-stream period
- 16 addresses
A fully associative LRU cache starts empty and requests address (i·s) mod 16. Hits move an address to the newest position; misses evict the oldest when full. Playback starts with 16 requests and adds two per second, capped at 4096 explicitly simulated requests. This toy stream is not a processor-cache benchmark. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forA compact layout helps when its actual access pattern benefits, not merely because a node has a smaller label.
Pause & reason
Check your understanding
Your turn
Try it yourself
Ten conceptual keys share a twelve-byte prefix and have four-byte suffixes. Find raw key bytes, factored key bytes, and the potential prefix-byte saving before metadata.
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Compare ten full prefix-plus-suffix strings with one prefix and ten suffixes.
Compare with the solution
The raw strings total 10×(12+4)=160 bytes. Factored key material totals 12+10×4=52 bytes. The difference is 108 bytes, also (10−1)×12. Node headers, references, terminal markers, alignment, and retained full keys can change the real structure's total, so this is a narrowly defined key-material calculation.
Keep the idea
Take it with you
- Compressed paths still require correct prefix and full-key validation.
- Adaptive branch layouts and path compression solve different storage problems.
- Ordering and performance depend on encoding, complete memory layout, and workload.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.