code wiki / _hdl_build / nx_galx_repair.nx
nx_galx_repair.nx
buildroot/runtime/_hdl_build/nx_galx_repair.nx
about
nx_galx_repair.nx -- recover the index entries the builder silently drops.
FOUND BY MEASURING THE WHOLE POPULATION, NOT A SAMPLE. nx_galx_audit emitted two counters for the
same set -- `header_entries 235,555` and `occupied 233,312` -- and the 2,243 gap reconciled
EXACTLY with the TSV rows whose char-69 is not a tab.
★★★★★★ TWO COUNTERS OF THE SAME POPULATION ARE A FREE AUDIT; ONE COUNTER IS A CLAIM.
The builder counts every newline into n_entries but only PLACES rows it can frame, so 2,243
images were counted, dropped, and never servable -- with no error, and a header that said they
were there.
The classes, measured (they sum to the 2,243, no residual):
1,171 no cid at all — 622 empty lines + 549 lines starting with a tab (path, no cid)
619 cid field 138 chars = TWO 69-char cids run together
327/106/10 cid field 74-76 chars
5 207 chars = THREE cids run together
138 = 2x69 and 207 = 3x69 is the signature of a writer that never terminated its line: the row
was flushed as a bare `<cid>` with no tab, no path and no newline, and the next row landed on it.
⇒ THE PATH FOR THOSE CIDS IS NOT IN THIS FILE AT ALL. It cannot be parsed back out; it has to be
recovered from somewhere else. Two somewhere-elses exist:
B) an orphaned cid whose blob is still on disk at the conventional <blobdir><cid>.png
C) an orphaned PATH whose cid can be RECOMPUTED from the image's own GENREC factors
★ A ROW THAT CANNOT BE PARSED IS NOT NECESSARILY DATA THAT IS LOST — ASK WHAT ELSE KNOWS IT.
Usage: nx_galx_repair <tsv> <idx> <blob> <blobdir> [--apply]
Dry run by default. The insert is idempotent, so --apply is safe to repeat.
license_tier: ORIGINAL
dependencies 5 imports · 0 importers
imports: nx_syscalls.nxnx_strconv.nxnx_store_ingest.nxnx_galx_cid_index.nxnx_galx_cidput.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 33 | const RP_MAGIC_1024: i64 = 1024 |
| 34 | const RP_MAGIC_4096: i64 = 4096 |
| 36 | const RP_CIDLEN: i64 = 69 |
| 37 | const RP_MAXPNG: i64 = 33554432 |
functions
| 39 | func rp_puts(s: *u8) -> i64 { |
| 44 | func rp_i(v: i64) -> i64 { |
| 50 | func rp_eol(buf: *u8, n: i64, from: i64) -> i64 {
called by 1: main |
| 62 | func rp_ishex(c: i64) -> i64 {
called by 1: rp_iscid |
| 70 | func rp_iscid(buf: *u8, at: i64, lim: i64) -> i64 { |
| 84 | func rp_slurp(path: *u8, out: *u8, cap: i64) -> i64 { |
| 99 | func main(argc: i64, argv: *i64) -> i64 { |