B2.3 · The CHAMP Property Database — manuscript chapter 2.3
A snapshot is a structure, not a copy.
Chapter 2.2's stores own the present perfectly; the desk asks questions in other tenses — what did the book look like at 14:30, show me the portfolio as-of yesterday's close, fork this risk scenario and mutate the copy. The CHAMP forest is the BEAM-native answer: structural sharing as the snapshot mechanism, the contract hash as the trie's placement function — the part preface's guideline, cashed here with words counted.
The chapter is content/bcs2.3.md. The implementation is the Operator's production
drop — three modules, 1,458 lines, delivered on June 7 — integrated under review with one gated
amendment; the rung behind it is bcs2.3, and its committed transcript closes PASS 7/7.
The tenses the flat table cannot serve
content/bcs2.3.md · WhyThe moment history or hypotheticals become product features, every answer from the flat table is a snapshot, and a snapshot of an ETS table is a copy-out priced per row. Structural sharing is the BEAM-native alternative — the immutable heap was built for exactly this — and this chapter cashes the guideline with words counted.
Integrated under review
The production-drop pattern returns in its original direction: three modules, 1,458 lines, delivered on June 7 — and the review earned its keep.
One placement law, in-process too
The drop's placement hash was a one-round mix; it now delegates to the contract's
hash32 — three lines and a comment, gated by H1.
Marginal cost, not a percentage
The first sharing metric capped near fifty and failed a correct implementation; marginal cost is the metric of record — gated by H2 and H3.
Both directions, measured
The flat table wins the present; the forest wins history categorically — and the chronology trade is named on stage. Gated by H4–H7.
The proof
content/bcs2.3.md · quoting bcs_rung_2_3_check.outThe full committed transcript, verbatim — the [debug] boot line stays
because the drop logs its starts, and the record keeps the drop's voice:
H1 canon ok -- placement delegated to the contract hash: compute_hash_int -> BrandedId.hash32; reference snowflake round-trips H2 persist ok -- the old snapshot is intact: v1 holds 1000, v2 holds 1001, and v1 cannot see the new row H3 sharing ok -- structural sharing measured: v2 costs 122 words beside v1 (one path copy) against 6688 standalone -- 98% of v2 is shared with v1 H4 forest ok -- two kinds, one forest: namespace_size AST=500 ORD=500 from the cached census, partition exact H5 hotpath ok -- by-snowflake 1858 ns/op vs string-id 2344 ns/op over 20000 puts H6 crossover ok -- at 20000 rows -- build: champ 41 ms vs ets 7 ms; point read: champ 799 ns vs ets 315 ns; snapshot: 1000 champ snapshots in 90 us (a snapshot is a binding) vs one ets copy-out in 2540 us 07:31:13.583 [debug] ChampServer started with 0 entries H7 server ok -- read scale-out: 10000 server calls 28 ms vs snapshot-once-then-pure 8 ms (copy cost included) PASS 7/7
The integrated modules live at runtimes/elixir/lib/echo_data/champ/ —
branded_champ.ex, champ_node.ex, champ_server.ex — with the drop's
provenance and the single amendment recorded in the source comment. The documented surface:
put/3, fetch/2, the *_by_snowflake family, get_namespace/2,
namespace_size/2, get_champ/1.
Boundaries, as the manuscript states them: writes serialize through the owning process;
chronological reads over the forest are a sort or a sibling index; no disk persistence — the durability
story remains where Part II put it; GC interplay under heavy version churn is real and unmeasured here.
The BCS-grade shell — namespace-scoped, Bcs.gate at every call, typed errors — is the
carried integration rung, not a patch smuggled into the drop.
The dives
three lessons, fixed by the chapter specThe Forest and the Placement Law
H1 — the namespace→trie forest keyed by the snowflake integer;
compute_hash_int -> BrandedId.hash32 — one placement law, in-process too; the
two-bitmap CHAMP node: datamap/nodemap, popcount-indexed, 5-bit
fragments.
Sharing at the Honest Metric
H2 — v1 holds 1000, v2 holds 1001, the new row absent from v1. H3 — 122 words beside
v1, 98% shared, against 6688 standalone; the denominator trap, documented so it is paid for once.
The Crossover
H4–H7 — the forest census, the by-snowflake hot path, the crossover stated plainly in both directions, chronology lost to hash order, the snapshot-out pattern, the tense litmus.
Part II continues past this module — Archetypes and Composition (B2.4) composes definitions at read time by a pure fold, and Relations Are Systems (B2.5) promotes edges to systems.
References
sources · relatedSources
- Steindorfer & Vinju — Optimizing Hash-Array Mapped Tries (OOPSLA 2015)the two-bitmap node, popcount indexing, the canonical representation
- Erlang/OTP — the ets modulethe flat-table comparison arm; the copy-out a snapshot costs there
Related
- B2 — The Elixir BCS Corethe chapter landing; the Part II arc
- B2.2 — Property Stores on ETSthe flat table the crossover measures against
- B2.4 — Archetypes and Compositionthe snapshot lane resolving against this forest
- B2.5 — Relations Are Systemsthe next promotion: edges under their own owner
- Redis Patterns Appliedthe substrate door — keyspaces, ordered reads, snapshots elsewhere
- Functional Programming in Elixirthe umbrella where echo_data lives