code wiki / (root) / nx_segopen_incr_gate.nx

nx_segopen_incr_gate.nx

buildroot/runtime/nx_segopen_incr_gate.nx

27743 B512 linesdepth 3pulls 4 transitivereach 0 importersview sourcekind gate/proof
docsdependenciesstructsconstsfunctions

about

nx_segopen_incr_gate.nx -- THE REFEREE FOR ss_open3's INCREMENTAL, WARM-PRESERVING REOPEN (search plan rung L1 ss_open_incr, 2026-09-02). THE CLAIM UNDER TEST: when the manifest is a strict prefix-extension of the handle a caller already holds, ss_open3(prefix, 1, prev, 1) reuses prev's segment mappings, live maps and key table, loads only the new rows, clears exactly the old marks the new rows shadow, and produces a handle whose every live map and every key->newest-row answer is BYTE-IDENTICAL to a FULL open of the same manifest. Any admission failure (no table retained, a leading name differs, a leading .docs size differs on disk, the manifest shrank) must fall back to FULL, ANNOUNCE its reason, and leave prev untouched. FIXTURE, built at runtime in /tmp/<gate>/ (never knowledge/store, which the segguard beat sweeps): three rows with overlapping keys -- A puts doc:1..40; B re-puts doc:11..20 and tombstones doc:21..25; C re-puts doc:16..18, tombstones doc:31..35 and adds doc:41..50 -- so the incremental step must clear marks in BOTH older rows (3 in B, 5 in A = 8) through a put AND a tombstone, and leave A's already-dead doc:21..25 alone. The expected mark counts are computed from the fixture, never read back from the subject: A 25 -> 20, B 10 -> 7, C 13 of 18. EVERY OUTCOME TOOTH IS PAIRED WITH A FIXTURE-REACHED TOOTH: mapping identity (the moved .docs pointer IS prev's), prev gutted after the move, the value read through the moved mapping AFTER prev is closed. GREEN iff every tooth passes; neg-controls named neg-control-* so the gate-law census can count them. license_tier: ORIGINAL expect_exit: 0

dependencies 3 imports · 0 importers

nx_seg_store.nx nx_syscalls.nx nx_gate_verdict.nx nx_segopen_incr_gate.nx

imports: nx_seg_store.nxnx_syscalls.nxnx_gate_verdict.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main gv_head gv_puts sys_write gv_ctr sys_mmap nxa_die sys_write ↻ sys_exit nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ gv_subjects gv_puts ↻ gv_num sys_mmap ↻ sys_write ↻ sys_munmap gv_need gv_puts ↻ sys_mkdir si_reset sys_mmap ↻ si_manifest_path ss_cat ss_writefile sys_openat_wr sys_write ↻ sys_close sys_fsync sys_mmap ↻ ss_begin_cap

structs

none

consts

21const SI_DIR: *u8 = "/tmp/nx_segopen_incr_gate"
22const SI_PREFIX: *u8 = "/tmp/nx_segopen_incr_gate/soi-"
23const SI_ERR_PREV: *u8 = "/tmp/nx_segopen_incr_gate/stderr-prev.txt"
24const SI_ERR_INCR: *u8 = "/tmp/nx_segopen_incr_gate/stderr-incr.txt"
25const SI_ERR_FULL: *u8 = "/tmp/nx_segopen_incr_gate/stderr-full.txt"
26const SI_ERR_NEG1: *u8 = "/tmp/nx_segopen_incr_gate/stderr-neg-notable.txt"
27const SI_ERR_NEG2: *u8 = "/tmp/nx_segopen_incr_gate/stderr-neg-prefix.txt"
28const SI_ERR_NEG3: *u8 = "/tmp/nx_segopen_incr_gate/stderr-neg-size.txt"
29const SI_ERR_NEG4: *u8 = "/tmp/nx_segopen_incr_gate/stderr-neg-shrank.txt"
30const SI_ERR_FOLD: *u8 = "/tmp/nx_segopen_incr_gate/stderr-fold.txt"
31const SI_ERR_FOLDFULL: *u8 = "/tmp/nx_segopen_incr_gate/stderr-fold-full.txt"
32const SI_ERR_FS: *u8 = "/tmp/nx_segopen_incr_gate/stderr-fold-ship.txt"
33const SI_ERR_UN: *u8 = "/tmp/nx_segopen_incr_gate/stderr-uncovered.txt"
34const SI_ERR_UNFULL: *u8 = "/tmp/nx_segopen_incr_gate/stderr-uncovered-full.txt"
35const SI_ERR_REO: *u8 = "/tmp/nx_segopen_incr_gate/stderr-reorder.txt"
36const SI_ERR_REOFULL: *u8 = "/tmp/nx_segopen_incr_gate/stderr-reorder-full.txt"
37const SI_D_LIVE: i64 = 27 // D = latest of A u B: 35 puts, minus C re-puts 16..18 and tombstones 31..35
38const SI_D_LIVE_AFTER_E: i64 = 24 // E re-puts doc:1..3
39const SI_E_LO: i64 = 1
40const SI_E_HI: i64 = 3
41const SI_E_RECS: i64 = 3
42const SI_FOLD_ENTRIES: i64 = 58 // 40 + 18 key entries over [D,C]
43const SI_MODE_DIR: i64 = 493 // 0755
44const SI_MODE_FILE: i64 = 420 // 0644
45const SI_SEGCAP: i64 = 65536
46const SI_KIND_LIVE: i64 = 1
47const SI_KIND_TOMB: i64 = 2
48const SI_KEYCAP: i64 = 64
49const SI_VALCAP: i64 = 64
50const SI_PATHCAP: i64 = 512
51const SI_MANCAP: i64 = 4096
52const SI_SAVED_FD: i64 = 20 // where fd 2 is parked while an open's stderr is captured
53const SI_A_LO: i64 = 1 // row A: doc:1..40 live
54const SI_A_HI: i64 = 40
55const SI_B_LO: i64 = 11 // row B: doc:11..20 re-put, doc:21..25 tombstoned -> 15 records
56const SI_B_HI: i64 = 20
57const SI_B_TLO: i64 = 21
58const SI_B_THI: i64 = 25
59const SI_C_LO: i64 = 16 // row C: doc:16..18 re-put, doc:31..35 tombstoned, doc:41..50 new -> 18 records
60const SI_C_HI: i64 = 18
61const SI_C_TLO: i64 = 31
62const SI_C_THI: i64 = 35
63const SI_C_NLO: i64 = 41
64const SI_C_NHI: i64 = 50
65const SI_A_RECS: i64 = 40
66const SI_B_RECS: i64 = 15
67const SI_C_RECS: i64 = 18
68const SI_A_LIVE_PREV: i64 = 25 // 40 - 10 re-put by B - 5 tombstoned by B
69const SI_B_LIVE_PREV: i64 = 10
70const SI_A_LIVE_AFTER: i64 = 20 // 25 - 5 tombstoned by C
71const SI_B_LIVE_AFTER: i64 = 7 // 10 - 3 re-put by C
72const SI_C_LIVE: i64 = 13 // 3 re-puts + 10 new; the 5 tombstones carry no mark
73const SI_SHADOWED: i64 = 8 // 3 in B + 5 in A
74const SI_ENTRIES: i64 = 73 // 40 + 15 + 18 key entries the table comparison must cover
75const SI_SUBJECTS: i64 = 16 // opens driven: prev, incr, full, no-table x2, size, reorder x3, shrank x3, fold x2, fold-ship, uncovered x2

functions

77func si_key(out: *u8, i: i64) -> i64
called by 2: si_add_rangemain calls 2: ss_catss_catn
84func si_manifest_path(prefix: *u8, out: *u8) -> i64
90func si_reset(prefix: *u8) -> i64
97func si_marks(h: *i64, s: i64, n: i64) -> i64
called by 1: main
106func si_seg_path(prefix: *u8, segname: *u8, suffix: *u8, out: *u8) -> i64
called by 1: main calls 1: ss_cat
113func si_contains(hay: *u8, hn: i64, needle: *u8) -> i64
called by 1: si_err_has
128func si_open_captured(prefix: *u8, errpath: *u8, prev: *i64, retain: i64) -> *i64
137func si_err_has(errpath: *u8, needle: *u8) -> i64
called by 1: main calls 3: sys_mmapss_readallsi_contains
144func si_add_range(wr: *i64, kind: i64, lo: i64, hi: i64, tag: *u8) -> i64
162func si_val_is(h: *i64, key: *u8, expect: *u8) -> i64
called by 1: main calls 2: sys_mmapss_hget
174func si_hget_kind(h: *i64, key: *u8) -> i64
called by 1: main calls 2: sys_mmapss_hget
180func si_lm_diff(ha: *i64, hb: *i64, s: i64, compared: *i64) -> i64
called by 1: main
196func si_table_diff(ha: *i64, hb: *i64, compared: *i64) -> i64
224func si_write_manifest(prefix: *u8, h: *i64, order: *i64, n: i64) -> i64
244func si_write_manifest_names(prefix: *u8, names: *i64, order: *i64, n: i64) -> i64
261func main(argc: i64, argv: *i64) -> i64