fix(pipeline): split the closure_plan log line over the itoa ring capacity

itoa_buf recycles a four-slot thread-local ring; the closure_plan line
passed six conversions in one call, so two fields printed corrupted --
the kernel-scale profile showed surface_changed reporting the elapsed-ms
value. Split into two calls of at most four conversions each.

The same profile run, for the record, answered the incremental cost
question with data (kernel corpus, one-file closure, worker total
238.5s): dump/publish 149.1s (62.5%), graph load 38.3s (16.1%),
wholesale semantic-edges post-pass 18.1s, manifest hashing ~20s by
residual -- while the repair itself (extract + resolve + registry
rehydration) is 0.57s. The closure algorithm is effectively free at
every scale; the remaining cost is generational I/O, which is the
delta-merge (copy -> patch -> rename) follow-up's target.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This commit is contained in:
Martin Vogel
2026-08-03 20:11:10 +02:00
parent 1ef7b026c9
commit d8fffd0460
+5 -1
View File
@@ -1735,9 +1735,13 @@ static int closure_try_plan(cbm_pipeline_t *p, cbm_store_t *store, const char *p
}
plan->n_changed = n_changed;
plan->n_dependents = dependent_count;
/* Two calls, not one: itoa_buf recycles a four-slot ring, so six
* conversions in a single call print two corrupted fields (observed:
* surface_changed reporting the elapsed-ms value at kernel scale). */
cbm_log_info("incremental.closure_plan", "changed", itoa_buf(n_changed), "surface_changed",
itoa_buf(n_surface_changed), "deleted", itoa_buf(n_deleted), "dependents",
itoa_buf(dependent_count), "closure", itoa_buf(plan->count), "elapsed_ms",
itoa_buf(dependent_count));
cbm_log_info("incremental.closure_plan_done", "closure", itoa_buf(plan->count), "elapsed_ms",
itoa_buf((int)elapsed_ms(t)));
done: