code wiki / (root) / nx_segstore_uncap_gate.nx

nx_segstore_uncap_gate.nx source

↩ module page · 128 lines · 6548 B

1// nx_segstore_uncap_gate.nx -- ISOLATED proof that the seg_store legacy-cap class is EATEN at the organ: 2// (1) ss_next_segid = canonical UNCAPPED writer segid (max+1) -- no clobber past the legacy cap; 3// (2) ss_manifest_dyn sees the WHOLE store while legacy ss_manifest stays byte-identical (capped) -- 4// the discriminating pair proving old callers keep exact behavior (API contract stability); 5// (3) the ss_scan_seglist version WINDOW slides (oldest out, latest kept): a high-churn key (every 6// registry's __idx__ gains one version per put) now reads back its LATEST version past the window -- 7// pre-fix ss_get returned the stale FIRST-window version (this is the "writes claim-OK but don't 8// surface" symptom class); 9// (4) ss_compact with a FRESH segid folds the >cap store to ONE segment with nothing lost. 10// Fresh /tmp store (never a shared registry). Runner must clean /tmp/ssuncap first. Exit 0 only on all-PASS. 11// license_tier: ORIGINAL expect_exit: 0 12import "nx_syscalls.nx" 13import "nx_seg_store.nx" 14 15const GATE_N: i64 = 300 // commits to drive -- chosen ABOVE the legacy cap so the tail exercises it 16const GATE_LEGACY_CAP: i64 = 256 // the legacy ss_manifest cap (must STILL cap -- byte-identical old API) 17const GATE_SEG_SLOTS: i64 = 260 // legacy caller buffer sizing convention (slots) 18const GATE_CHECKS: i64 = 9 // number of PASS conditions below 19const KEY_CH: i64 = 107 // 'k' record-key prefix 20const VAL_CH: i64 = 118 // 'v' record-value prefix 21const HOTV_CH: i64 = 104 // 'h' hot-key value prefix 22const ASCII_0: i64 = 48 23const DIR_MODE: i64 = 0x1ed // 0755 24 25func g_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 26func g_putn(v: i64) -> i64 { 27 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 } 28 var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 29 let d: *u8 = sys_mmap(24); var k: i64 = 0 30 while m > 0 { d[k] = (ASCII_0 + (m % 10)) as u8; m = m / 10; k = k + 1 } 31 let o: *u8 = sys_mmap(24); var i: i64 = 0 32 while i < k { o[i] = d[k-1-i]; i = i + 1 } sys_write(1, o, k) 33 return 0 34} 35// build <c><i> (e.g. "k42") into buf, NUL-terminated; return length 36func g_id(buf: *u8, c: i64, i: i64) -> i64 { 37 buf[0] = c as u8 38 var o: i64 = 1; var m: i64 = i 39 if m == 0 { buf[o] = ASCII_0 as u8; o = o + 1; buf[o] = 0 as u8; return o } 40 let t: *u8 = sys_mmap(24); var k: i64 = 0 41 while m > 0 { t[k] = (ASCII_0 + (m % 10)) as u8; m = m / 10; k = k + 1 } 42 while k > 0 { buf[o] = t[k-1]; o = o + 1; k = k - 1 } 43 buf[o] = 0 as u8 44 return o 45} 46// 1 if ss_get(prefix,key) returns FOUND with bytes exactly equal to want[0..wlen) 47func g_get_eq(prefix: *u8, key: *u8, want: *u8, wlen: i64) -> i64 { 48 let po: *i64 = sys_mmap(16) as *i64 49 let lo: *i64 = sys_mmap(16) as *i64 50 if ss_get(prefix, key, po, lo) != 1 { return 0 } 51 if lo[0] != wlen { return 0 } 52 let src: *u8 = po[0] as *u8 53 var i: i64 = 0 54 while i < wlen { if src[i] != want[i] { return 0 } i = i + 1 } 55 return 1 56} 57func g_check(name: *u8, ok: i64, pass: *i64) -> i64 { 58 g_puts("T " as *u8); g_puts(name); g_puts(" -> " as *u8) 59 if ok == 1 { g_puts("PASS\n" as *u8); pass[0] = pass[0] + 1 } else { g_puts("FAIL\n" as *u8) } 60 return 0 61} 62 63func main(argc: i64, argv: *i64) -> i64 { 64 let pass: *i64 = sys_mmap(16) as *i64 65 pass[0] = 0 66 sys_mkdir("/tmp/ssuncap" as *u8, DIR_MODE) 67 let prefix: *u8 = "/tmp/ssuncap/su-" as *u8 68 let idbuf: *u8 = sys_mmap(64) 69 let valbuf: *u8 = sys_mmap(64) 70 let hotbuf: *u8 = sys_mmap(64) 71 72 // drive GATE_N commits; EVERY commit also advances the hot key (versions = GATE_N > window) 73 var w: i64 = 0 74 while w < GATE_N { 75 g_id(idbuf, KEY_CH, w) 76 let vl: i64 = g_id(valbuf, VAL_CH, w) 77 let hl: i64 = g_id(hotbuf, HOTV_CH, w) 78 let wr: *i64 = ss_begin() 79 ss_add(wr, 1, idbuf, valbuf, vl) 80 ss_add(wr, 1, "__hot__" as *u8, hotbuf, hl) 81 ss_commit(prefix, wr, ss_next_segid(prefix)) 82 w = w + 1 83 } 84 85 // T1 canonical writer segid is UNCAPPED 86 g_check("next-segid-uncapped" as *u8, (ss_next_segid(prefix) == GATE_N) as i64, pass) 87 88 // T2 legacy ss_manifest STILL caps exactly (byte-identical old API preserved) -- the discriminator 89 let legacy: *i64 = sys_mmap(8 * GATE_SEG_SLOTS) as *i64 90 g_check("legacy-manifest-still-capped" as *u8, (ss_manifest(prefix, legacy) == GATE_LEGACY_CAP) as i64, pass) 91 92 // T3 dyn manifest sees the WHOLE store 93 let dp: *i64 = sys_mmap(16) as *i64 94 g_check("dyn-manifest-sees-all" as *u8, (ss_manifest_dyn(prefix, dp) == GATE_N) as i64, pass) 95 96 // T4 record PAST the legacy cap reads back exactly 97 g_id(idbuf, KEY_CH, GATE_N - 1) 98 let vl4: i64 = g_id(valbuf, VAL_CH, GATE_N - 1) 99 g_check("tail-record-readback" as *u8, g_get_eq(prefix, idbuf, valbuf, vl4), pass) 100 101 // T5 HOT KEY: latest version wins past the window (pre-fix: stale first-window version) -- THE fix 102 let hl5: i64 = g_id(hotbuf, HOTV_CH, GATE_N - 1) 103 g_check("hot-key-latest-not-stale" as *u8, g_get_eq(prefix, "__hot__" as *u8, hotbuf, hl5), pass) 104 105 // T6 earliest record still intact (slide corrupted nothing) 106 g_id(idbuf, KEY_CH, 0) 107 let vl6: i64 = g_id(valbuf, VAL_CH, 0) 108 g_check("first-record-intact" as *u8, g_get_eq(prefix, idbuf, valbuf, vl6), pass) 109 110 // T7 compact with a FRESH segid folds the whole >cap store... 111 let crc: i64 = ss_compact(prefix, ss_next_segid(prefix)) 112 g_check("compact-fresh-segid-ok" as *u8, (crc > 0) as i64, pass) 113 // T8 ...to exactly ONE live segment... 114 g_check("compact-folds-to-one" as *u8, (ss_manifest_dyn(prefix, dp) == 1) as i64, pass) 115 // T9 ...with latest state fully preserved (hot key + tail record). 116 // regenerate the expected value: valbuf was reused for T6 (v0) -- comparing against it was a gate bug. 117 var ok9: i64 = 1 118 if g_get_eq(prefix, "__hot__" as *u8, hotbuf, hl5) != 1 { ok9 = 0; g_puts(" (hot-key lost)\n" as *u8) } 119 g_id(idbuf, KEY_CH, GATE_N - 1) 120 let vl9: i64 = g_id(valbuf, VAL_CH, GATE_N - 1) 121 if g_get_eq(prefix, idbuf, valbuf, vl9) != 1 { ok9 = 0; g_puts(" (tail record lost)\n" as *u8) } 122 g_check("compact-preserves-latest" as *u8, ok9, pass) 123 124 g_puts("SEGSTORE-UNCAP-GATE pass=" as *u8); g_putn(pass[0]); g_puts("/" as *u8); g_putn(GATE_CHECKS); g_puts(" verdict=" as *u8) 125 if pass[0] == GATE_CHECKS { g_puts("GREEN\n" as *u8); return 0 } 126 g_puts("RED\n" as *u8) 127 return 1 128}