|
| 1 | +// Cache key dispatch — flat three-way fallback, top-down flow. |
| 2 | +// Rendered to figs/fig1_dispatch_flow.png via `make flowchart`, then |
| 3 | +// composed with the rasterized derivation listing (figs/alg_hash.typ) |
| 4 | +// into figs/fig1_dispatch.png by figs/compose_fig1.py. |
| 5 | +// |
| 6 | +// A per-ref dispatch tries three categories in order: |
| 7 | +// 1. Pure — immutable primitives, hash the value directly. |
| 8 | +// 2. ContentAddressed — buffer-protocol bytes, hash the buffer. |
| 9 | +// 3. ExecutionPath — fall back to the producing cell's stored H. |
| 10 | +// All three feed the same sha256 combiner at the bottom, which |
| 11 | +// concatenates the per-ref keys with the cell's compiled bytecode to |
| 12 | +// produce H(cell). |
| 13 | + |
| 14 | +digraph dispatch { |
| 15 | + rankdir = TB; |
| 16 | + graph [bgcolor="transparent", fontname="serif", fontsize=11, |
| 17 | + nodesep=0.25, ranksep=0.32]; |
| 18 | + node [fontname="serif", fontsize=10, color="#333333", penwidth=0.9, |
| 19 | + margin="0.10,0.05"]; |
| 20 | + edge [fontname="serif", fontsize=9, color="#555555", arrowsize=0.7]; |
| 21 | + |
| 22 | + // ── entry ───────────────────────────────────────────────────── |
| 23 | + ref [label="per ref", |
| 24 | + shape=box, style="rounded,filled", fillcolor="#f5f5f5"]; |
| 25 | + |
| 26 | + // ── decisions ──────────────────────────────────────────────── |
| 27 | + q_pure [label="immutable?", |
| 28 | + shape=diamond, style=filled, fillcolor="#e3f2fd"]; |
| 29 | + q_buf [label="buffer\nprotocol?", |
| 30 | + shape=diamond, style=filled, fillcolor="#e8f5e9"]; |
| 31 | + |
| 32 | + // ── three terminal categories ──────────────────────────────── |
| 33 | + pure [label="Pure\nsha256(value)", |
| 34 | + shape=box, style="rounded,filled", fillcolor="#e3f2fd"]; |
| 35 | + ca [label="ContentAddressed\nsha256(buffer)", |
| 36 | + shape=box, style="rounded,filled", fillcolor="#e8f5e9"]; |
| 37 | + ep [label="ExecutionPath\nH(parent)", |
| 38 | + shape=box, style="rounded,filled", fillcolor="#fff3e0"]; |
| 39 | + |
| 40 | + // ── combiner + output (bottom) ─────────────────────────────── |
| 41 | + src [label="cell bytecode\nsha256(bytecode)", |
| 42 | + shape=box, style="rounded,filled", fillcolor="#f5f5f5"]; |
| 43 | + combine [label="combine keys\nsha256(src ‖ k₁ ‖ k₂ ‖ …)", |
| 44 | + shape=box, style="rounded,filled", fillcolor="#fafafa"]; |
| 45 | + out [label="H(cell)", |
| 46 | + shape=oval, style=filled, fillcolor="#fff9c4"]; |
| 47 | + |
| 48 | + // ── flow ──────────────────────────────────────────────────── |
| 49 | + ref -> q_pure; |
| 50 | + q_pure -> pure [label="yes"]; |
| 51 | + q_pure -> q_buf [label="no"]; |
| 52 | + q_buf -> ca [label="yes"]; |
| 53 | + q_buf -> ep [label="no"]; |
| 54 | + |
| 55 | + pure -> combine; |
| 56 | + ca -> combine; |
| 57 | + ep -> combine; |
| 58 | + src -> combine; |
| 59 | + combine -> out; |
| 60 | + |
| 61 | + // decisions on the spine, terminals beside them |
| 62 | + { rank=same; q_pure; pure; } |
| 63 | + { rank=same; q_buf -> ca -> ep [style=invis]; } |
| 64 | + { rank=same; src; combine; } |
| 65 | +} |
0 commit comments