From 270ba93fbe372aae003b10bf25a935b293ae3573 Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Wed, 30 Sep 2026 20:13:49 +0200 Subject: [PATCH] Name a failed step's index in drawSteps' panics, and quote the decision's measurement as the experiment it was --- docs/decisions.md | 11 ++++++----- path.go | 9 +++++---- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/decisions.md b/docs/decisions.md index e5fc422..cc12a65 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -591,7 +591,7 @@ is until a real data set needs the indexed form. 2026-09-17, Lilleman auf Larv. A path that fails below its first level then moves no seeded stream, at the cost of one -draw-free walk per call, which allocates nothing. +draw-free walk per call, which allocates nothing up to 16 steps. ## A country's postal codes and streets are siblings under its locality @@ -848,8 +848,9 @@ the direct chain is the one a reader can predict from the tables' parents. replaces "The path walks are separate loops". Goals 2 and 11: `drawSteps` draws every path from its steps, compiled at link by `pathCheck` or, for a caller's path, by `probePath` into a stack buffer. The check and -the probe stay two loops: one loop leaks the check's leaves and errors with the draw's -state, since Go tracks a struct's fields as one, and a repeat of a reference path rose -from 66 to 106 allocations. `drawSteps` takes its state as parameters and a step holds -no node, so no benchmark gained an allocation. Valid while Go's escape analysis tracks +the probe stay two loops: on 2026-09-29 one loop over all three walks, switching on a +mode field, leaked the check's leaves and errors with the draw's pins, arm and memo, +since Go tracks a struct's fields as one, and a repeat of a reference path rose from 66 +to 106 allocations. `drawSteps` takes its state as parameters and a step holds no node, +so no benchmark gained an allocation. Valid while Go's escape analysis tracks a struct's fields as one. diff --git a/path.go b/path.go index b08c7fb..c4f1307 100644 --- a/path.go +++ b/path.go @@ -187,7 +187,8 @@ func (t *table) route(tail []string, descended bool) (tableRoute, error) { } // pathStep is one step of a compiled path, taken at the node the steps before it -// reached; at indexes the tail segment the step consumes. A step holds no node, so a +// reached, a choice there resolved first; at indexes the tail where it is taken, and +// only a table's step sits past the tail's end. A step holds no node, so a // caller's steps stay on its stack. type pathStep struct { kind stepKind @@ -199,7 +200,7 @@ type pathStep struct { type stepKind uint8 const ( - stepField stepKind = iota + 1 // into a field of the template at this level, a choice there resolved first + stepField stepKind = iota + 1 // into a field of the template at this level stepSelect // pin the selected row of the table stepDraw // draw a row of the table inside the pins stepRow // land on the table's row node @@ -374,13 +375,13 @@ func drawSteps(s *generatorState, n node, steps []pathStep, pins *pinSet, memo * if st.kind == stepField { var err error if n, err = stepInto(n, st.name); err != nil { - panic(internalError("%v; a path's steps should have been compiled from the node they are drawn from", err)) + panic(internalError("step %d: %v; a path's steps should have been compiled from the node they are drawn from", st.at, err)) } continue } t, ok := n.(*table) if !ok { - panic(internalError("a table's step %q on %T", st.name, n)) + panic(internalError("step %d: a table's step of kind %d on %T", st.at, st.kind, n)) } n = t.drawStep(s, st, pins) }