惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

美团技术团队
罗磊的独立博客
SecWiki News
SecWiki News
The Register - Security
The Register - Security
The GitHub Blog
The GitHub Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
S
Schneier on Security
IT之家
IT之家
博客园 - 聂微东
T
The Exploit Database - CXSecurity.com
Recorded Future
Recorded Future
大猫的无限游戏
大猫的无限游戏
Know Your Adversary
Know Your Adversary
Latest news
Latest news
Vercel News
Vercel News
G
GRAHAM CLULEY
D
DataBreaches.Net
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
SegmentFault 最新的问题
博客园_首页
雷峰网
雷峰网
T
Tenable Blog
Spread Privacy
Spread Privacy
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
酷 壳 – CoolShell
酷 壳 – CoolShell
Cisco Talos Blog
Cisco Talos Blog
V
Visual Studio Blog
J
Java Code Geeks
博客园 - Franky
The Cloudflare Blog
Apple Machine Learning Research
Apple Machine Learning Research
C
CERT Recently Published Vulnerability Notes
T
Threatpost
Google DeepMind News
Google DeepMind News
F
Fortinet All Blogs
P
Privacy International News Feed
T
Threat Research - Cisco Blogs
T
The Blog of Author Tim Ferriss
V
Vulnerabilities – Threatpost
Recent Announcements
Recent Announcements
Blog — PlanetScale
Blog — PlanetScale
Security Latest
Security Latest
U
Unit 42
M
MIT News - Artificial intelligence
Y
Y Combinator Blog
K
Kaspersky official blog
有赞技术团队
有赞技术团队
B
Blog
腾讯CDC

Software Design: Tidy First?

The Cost YAGNI Was Never About Why So Literal? Smalltalk Genie Hey, N00b, We Didn't Hire You to Complete Tasks A Learning System Made of Learning Parts You Don't Get to Create Anything Trust Factory Genie Lessons from Genie Sessions: Prose as a Programming Language Scope Is The Steering Wheel Itchy Brain Thinkies World Congress II: May 20, 2026 Thinkie: Wider Scope Thoughts, Not Thinking? Did We Do This to Ourselves? Genie Sessions: Run, Right, and Fast for the Adaptive Radix Tree Unstick Your Stuck Thinking Genie Tarpit Genie Lessons: Nobody Wants Agents Passing Tests Bore Me
Adaptive Radix Tree
Kent Beck · 2026-05-05 · via Software Design: Tidy First?

This and the following chapters are from a forthcoming book: Adaptive Radix Tree: Sorted Maps For Fun & Profit

This tutorial assumes you’re a Go programmer who’s used map[K]V and has reached for a sorted map at some point — google/btree, google/btree, or one of the third-party red-black tree libraries — and got a feel for the API. It does not assume you know what a trie is or how an Adaptive Radix Tree differs from one.

Each chapter builds a working sorted map. Chapter 1 is the simplest imaginable trie. Chapters 2 through 7 each add one decision: lazy expansion, path compression, smaller node types, polymorphism. By chapter 8 you can read the project’s main art.Tree source as a known artifact rather than a wall of code. This chapter is just the primer — no Go yet.

A sorted map is a map[K]V whose iteration order is the natural ascending order of K, not insertion order or hash order. The operations are familiar:

Put(k, v) // insert or replace
Get(k)    // (v, ok)
Delete(k) // remove if present
Len()     // count
Range(kFrom, kTo)     // iterator in ascending key order

Two well-known data structures offer this API:

  • Hash maps with side indexes (e.g. map[K]V plus a sorted slice you maintain by hand). Lookups are O(1), but every mutation costs O(n) on the slice or O(log n) on a heap, and the iteration order is whatever you paid to maintain.

  • Self-balancing BSTs — red-black, AVL, B-tree. Lookups, inserts, and deletes are O(log n); iteration is a tree walk. These compare keys as opaque blobs: every comparison reads every byte of the key until it finds a difference.

Tries take the third path: don’t compare keys; walk them.

A trie (”retrieval tree”, traditionally pronounced try) is a tree where each edge is labelled with one element of the key (a byte, in our case), and the path from root to a node is the prefix of every key reachable below it. There is no key comparison. Lookup reads the key byte-by-byte and follows the edge labelled with that byte.

The trie was invented during the Cambrian data structure explosion.

  • René de la Briandais (1959) — “File Searching Using Variable Length Keys,” Proceedings of the Western Joint Computer Conference. First published description of the structure.

  • Edward Fredkin (1960) — “Trie Memory,” Communications of the ACM 3(9):490–499. Coined the name trie (pronounced “try”) from the middle syllable of retrieval.

An ASCII picture of the keys {hello:1, hi:2, help:3}:

Two consequences fall out for free:

  1. Sorted iteration is automatic. At each node, visit children in ascending byte order. The yielded keys appear in byte-wise sorted order with no comparisons and no balancing.

  2. Shared work for shared prefixes. A lookup of help and a lookup of hello traverse the same first four edges. The per-byte cost depends on the keys’ shape, not on the size of the map.

The honest tradeoffs are equally direct:

  • One node-traversal per byte. A 16-byte key is 16 pointer dereferences down the tree. If the tree is bigger than your L1 cache, that’s 16 cache misses. A B-tree comparing the same key against a few interior keys is fewer dereferences but each comparison reads more bytes; the right answer depends on the workload.

  • Wasted nodes for sparse keysets. Every byte position where any key has a unique value gets its own node. If your keys are random 16-byte blobs, almost every level branches, and you pay for one inner node per byte per key. Chapter 1 makes this visible: ~33 MB to store 1 000 random 16-byte keys in the simplest possible trie.

The book is structured according to the principles of David Parnas and Paul Clements's 1986 paper A Rational Design Process: How and Why to Fake It. The first chapter introduces a simple-but-slow implementation. Each of the seven succeeding chapters addresses the slowness of the previous chapter until we have the whole ART.

  • Only full-sized nodes (chapter 1)—we build a whole working tree out of nodes that assume all 256 children are valid. (Foreshadowing—this will turn out to be a useful disaster.)

  • Lazy expansion (chapter 2)—stop allocating inner nodes along a tail with no siblings.

  • Path compression (chapter 3)—let one node represent several consecutive bytes when none of them branch.

  • Small node type (chapter 4)—stores up to 4 keys.

  • Polymorphism (chapter 5)—we’re going to add more node sizes, so why don’t we make it easy? (Make the hard change easy, then make the easy change.)

  • In between node types (chapters 6 & 7)—save space at the cost of computation by filling in nodes with up to 16 & then 48 keys. (Of course it’s more interesting than a simple tradeoff when space saving reduces memory pressure & thus saves time.)

  • Polish (chapter 8)—inline-key buffers, embedded headers, a reused path buffer for Range. Allocations per key drop to roughly one.

By chapter 8 the implementation is the same shape as the production art.Tree in the parent package. You will have built it, decision by decision, and you will have measured what each decision was worth.

Viktor Leis, Alfons Kemper, and Thomas Neumann at the Technical University of Munich published the adaptive radix tree first.

Published as “The Adaptive Radix Tree: ARTful Indexing for Main-Memory Databases” at ICDE 2013. PDF: https://db.in.tum.de/~leis/papers/ART.pdf

Onward to chapter 1, where we build the disaster. Well, the naive, memory wasteful version.