nx_flatstore_flip.nx source
↩ module page · 107 lines · 5067 B
1// nx_flatstore_flip.nx -- the GENERIC store-law flip primitive (operator: "we arent supposed to be using .tsv").
2// Three hand-copied flips (nx_raci_sov, nx_adversarial_sov, nx_searchcompet_sov) proved the migrate/verify/read
3// pattern is BOILERPLATE -> this DRYs it (rule 15) into ONE parameterized lib so every remaining flat-file debt
4// (the 655 the dataplane census measures) becomes a few-line caller: import + fsf_read_all(store,keyprefix,...)
5// with a self-seeding fallback. The store IS the SSOT; the flat file survives only as migrate-source.
6// The line-store contract: one text line per store row, keyed "<keyprefix><idx>", '#' comments + blank lines
7// skipped, CRLF tolerated -> fsf_read_all reconstructs the data lines byte-compatibly so a consumer flips its
8// file-read to a store-read with a ONE-LINE swap. license_tier: ORIGINAL module: nishi-core.architect.flatstore_flip
9import "nx_seg_store.nx"
10import "nx_syscalls.nx"
11const K_MAGIC_4096: i64 = 4096
12
13// build "<keyprefix><k>" into out (keyprefix is a NUL-terminated string, e.g. "adv:gate:")
14func fsf_key(keyprefix: *u8, k: i64, out: *u8) -> i64 {
15 var o: i64=0; var i: i64=0
16 while keyprefix[i]!=(0 as u8){ out[o]=keyprefix[i]; o=o+1; i=i+1 }
17 if k==0 { out[o]=48 as u8; o=o+1 } else { let t: *u8=sys_mmap(24); var m: i64=k; var n: i64=0; while m>0 { t[n]=(48+(m%10)) as u8; m=m/10; n=n+1 } var j: i64=0; while j<n { out[o]=t[n-1-j]; o=o+1; j=j+1 } }
18 out[o]=0 as u8; return 0
19}
20
21// MIGRATE the flat file's DATA lines (skip '#' + empty, CRLF-safe) into the seg_store keyed by index, then
22// byte-verify each row reads back. Re-seeds each call (the flat file is the static migrate-source until retired).
23// totp[0] <- total source rows; verp[0] <- verified rows. GREEN when verp==totp && totp>0.
24func fsf_migrate(conf: *u8, store: *u8, keyprefix: *u8, totp: *i64, verp: *i64) -> i64 {
25 let szp: *i64 = sys_mmap(16) as *i64
26 let buf: *u8 = ss_readall(conf, szp)
27 let sz: i64 = szp[0]
28 if sz <= 0 { totp[0]=0; verp[0]=0; return 0 }
29 let lp: *i64 = sys_mmap(8*K_MAGIC_4096) as *i64; let ll: *i64 = sys_mmap(8*K_MAGIC_4096) as *i64
30 var k: i64 = 0; var i: i64 = 0; var ls: i64 = 0
31 while i <= sz {
32 var nl: i64 = 0; if i>=sz { nl=1 } else { if buf[i]==(10 as u8) { nl=1 } }
33 if nl==1 {
34 var len: i64 = i - ls
35 if len>0 { if buf[ls+len-1]==(13 as u8) { len=len-1 } } // CRLF-safe
36 if len>0 { if (buf[ls] as i64) != 35 { if k<K_MAGIC_4096 { lp[k]=(buf as i64)+ls; ll[k]=len; k=k+1 } } } // skip '#'
37 ls = i+1
38 }
39 i=i+1
40 }
41 totp[0]=k
42 let w: *i64 = ss_begin()
43 var j: i64 = 0
44 while j<k { let rk: *u8=sys_mmap(128); fsf_key(keyprefix, j, rk); ss_add(w, 1, rk, lp[j] as *u8, ll[j]); j=j+1 }
45 ss_commit(store, w, sys_now_realtime_sec())
46 let h: *i64 = ss_open(store)
47 let pq: *i64=sys_mmap(16) as *i64; let lq: *i64=sys_mmap(16) as *i64
48 var ver: i64 = 0; var j2: i64 = 0
49 while j2<k {
50 let rk: *u8=sys_mmap(128); fsf_key(keyprefix, j2, rk)
51 if ss_hget(h, rk, pq, lq)==1 { if lq[0]==ll[j2] { let a: *u8=pq[0] as *u8; let b: *u8=lp[j2] as *u8; var eq: i64=1; var x: i64=0; while x<lq[0] { if a[x]!=b[x] { eq=0 } x=x+1 } if eq==1 { ver=ver+1 } } }
52 j2=j2+1
53 }
54 verp[0]=ver
55 return ver
56}
57
58// row k's bytes into out (NUL-terminated, capped), FROM THE STORE. len, or -1 past the last row (iteration sentinel).
59func fsf_row(store: *u8, keyprefix: *u8, k: i64, out: *u8, cap: i64) -> i64 {
60 let h: *i64 = ss_open(store)
61 if (h as i64)==0 { return 0 - 1 }
62 let pq: *i64=sys_mmap(16) as *i64
63 let lq: *i64=sys_mmap(16) as *i64
64 let rk: *u8=sys_mmap(128)
65 fsf_key(keyprefix, k, rk)
66 if ss_hget(h, rk, pq, lq)!=1 { return 0 - 1 }
67 var n: i64 = lq[0]
68 if n > cap - 1 { n = cap - 1 }
69 let src: *u8 = pq[0] as *u8
70 var i: i64=0
71 while i<n { out[i]=src[i]; i=i+1 }
72 out[n]=0 as u8
73 return n
74}
75
76// number of rows in the store under keyprefix (iterate until a gap)
77func fsf_count(store: *u8, keyprefix: *u8) -> i64 {
78 let h: *i64 = ss_open(store)
79 if (h as i64)==0 { return 0 }
80 let pq: *i64=sys_mmap(16) as *i64; let lq: *i64=sys_mmap(16) as *i64
81 var k: i64=0; var go: i64=1
82 while go==1 {
83 let rk: *u8=sys_mmap(128); fsf_key(keyprefix, k, rk)
84 if ss_hget(h, rk, pq, lq)==1 { k=k+1 } else { go=0 }
85 }
86 return k
87}
88
89// every row from the store, newline-joined, byte-compatible with the flat file's DATA lines (so a consumer flips
90// its file-read to this with a one-line swap). total bytes (0 if empty).
91func fsf_read_all(store: *u8, keyprefix: *u8, out: *u8, cap: i64) -> i64 {
92 var o: i64 = 0
93 var k: i64 = 0
94 var go: i64 = 1
95 while go == 1 {
96 let n: i64 = fsf_row(store, keyprefix, k, ((out as i64) + o) as *u8, cap - o - 1)
97 if n < 0 { go = 0 } else {
98 o = o + n
99 out[o] = 10 as u8
100 o = o + 1
101 k = k + 1
102 if o >= cap - 2 { go = 0 }
103 }
104 }
105 out[o] = 0 as u8
106 return o
107}