segview — cursors, total length and coalescing for segment views
The language holds one segment view operation, view_segments (build). This module gives the piece count (piece_count) and the i-th piece (piece_at), and adds cursors, total length and coalescing on top. The piece count and the i-th piece were the core ops segs and seg; they are written by reading fields and slicing, so they moved to this module when their names were freed (2026-10-16). The other three are written with those two, so there is no reason for them to be core ops.
Why segments is in the language. Without holding several segments as one value, sending them out takes one call per segment. Sending 64 KiB as 64 segments differed by 28× in the development repository’s measurement (one writev versus 64 writes). A segment is an iovec — a slice in emitted C has the same size and both offsets as struct iovec, so passing a segment array across an extern boundary is a cast, not a copy (a test compares it every run).
rem the descriptor is (at, n) pairs in a flat slice u64 --- no new struct type
set idx d. 0 . 0 . set idx d. 1 . 4 .
set idx d. 2 . 8 . set idx d. 3 . 4 .
let ss segments u8 view_segments back. d. . .
let n u64 segview.total_len ss. . .
let w option usize segview.coalesce ss. out. . .| Call | What it touches | Cost |
|---|---|---|
segview.piece_count · piece_at | descriptor only | a few ns or less per segment, zero copies |
segview.total_len | descriptor only | O(segments) |
segview.cursor · seek · byte_at | descriptor only | O(segments) — scans segments to find the position |
segview.coalesce | every byte | O(n) — the only place copying happens |
Table 50.1 — The cost is written in the op name
That is the point of the design — traversal only borrows segments, and the cost of flattening into one piece is paid only when called. The cost is visible at the call site.
Things to know. Storage belongs to the caller — coalesce writes into the given buffer and answers the length written; if the buffer is short it does not truncate but answers none. No cursor pointing to a nonexistent position is made — seek past the end is none.
One name hurt other modules. total_len was first called total. Then the library pair tests caught breakage when segview was used together with tls13 or tlssrv — it collided with a local variable total inside tls13 and produced an unrelated diagnostic (E-GUARD-FALLTHROUGH). Common words are not exported. (The diagnostic not reporting the name collision as a name collision is a separate remaining defect.)
Not built — variable element width (T of segments T is a scalar slice today), zero-copy optimisation of coalesce, the read-side (readv) counterpart.