docs(base): the table's observers, groups and chunks, sparse index values, block change stamps and the parallel-worker rule

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-27 22:08:19 +03:00
parent f3fec88888
commit 50aa535f88

View file

@ -75,6 +75,17 @@ allocates nothing per query:
- **Change detection.** `tb_advance(tb)` moves the table to its next tick; `tb_changed_since(tb,
tick, out)` and `tb_added_since` name the rows written since - what a save or a message needs to
send a delta instead of everything.
- **Observers.** `tb_on_add(tb, fn f)` / `tb_on_remove(tb, fn f)`: `f(handle)` (its states supplied,
like a system's) is told each handle as its row is made and before it goes.
- **Groups and chunks.** `tb_remove_all(tb, ix, v)` removes every row an index files under one
value - a kind, or a chunk of the world a stream lets go (`chunk_of(x, z, size)` packs a chunk's
cell into an int). An index keeps a small value (below 1024) in its own slot and gives a larger,
sparse one (a chunk's packed cell) a slot through a map, so each value costs one list.
- **Change detection is per 64-row block too**: `tb_changed_since` skips a block nobody wrote
since. A row moved into a removal's gap keeps its own tick; the removal is the observer's.
- **Parallel work reads, never writes, a state.** `Job.parallel_for(n, fn work, ctx)` over a
table's columns runs on every core; the compiler refuses a worker that takes a state as `mut`
(a result goes into `ctx`, a shared count through a `Sync` handle kept in the state).
- **Stable ids.** `IntMap` (`imap_new`, `imap_put`, `imap_get(m, k, none)`, `imap_del`) maps an
id kept in a save or a message to a handle without a scan.