code wiki / _hdl_build / nx_seg_schema.nx

nx_seg_schema.nx source

↩ module page · 69 lines · 3256 B

1// nx_seg_schema.nx -- CAP-SEG-SCHEMA: a self-describing schema + typing + backward/forward EVOLUTION layer for the 2// sovereign store (Avro-class). A schema = ordered fields {name, type, required}. It is SELF-DESCRIBING (sc_encode 3// packs it to bytes storable as a store record; sc_decode reads it back). Evolution safety is MECHANIZED and matches 4// the API-contract-stability doctrine: a new schema is a SAFE evolution of the old iff it (a) keeps every old field 5// with the same type -- no remove/rename/retype -- and (b) adds only OPTIONAL fields (a new REQUIRED field breaks old 6// records). A LIBRARY (no main -> run its _gate). license_tier: ORIGINAL 7import "nx_syscalls.nx" 8 9const SC_STR: i64 = 1 10const SC_INT: i64 = 2 11const SC_BYTES: i64 = 3 12const SC_OPT: i64 = 0 13const SC_REQ: i64 = 1 14const SC_SAFE: i64 = 0 15const SC_REMOVED: i64 = 1 16const SC_RETYPED: i64 = 2 17const SC_NEWREQ: i64 = 3 18 19func sc_streq(a: *u8, b: *u8) -> i64 { var i: i64=0; while a[i]!=(0 as u8) { if a[i]!=b[i] { return 0 } i=i+1 } if b[i]!=(0 as u8) { return 0 } return 1 } 20func sc_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 21func sc_w32(p: *u8, o: i64, v: i64) -> i64 { p[o]=((v>>24)&0xff) as u8; p[o+1]=((v>>16)&0xff) as u8; p[o+2]=((v>>8)&0xff) as u8; p[o+3]=(v&0xff) as u8; return o+4 } 22func sc_r32(p: *u8, o: i64) -> i64 { let a: i64=p[o]; let b: i64=p[o+1]; let c: i64=p[o+2]; let d: i64=p[o+3]; return (((((a<<8)|b)<<8)|c)<<8)|d } 23func sc_find(name: *u8, names: *i64, n: i64) -> i64 { var i: i64=0; while i<n { if sc_streq((names[i]) as *u8, name)==1 { return i } i=i+1 } return 0-1 } 24 25// self-describing encode: [u32be n] then per field [u8 type][u8 req][u32be namelen][name]. Returns bytes written. 26func sc_encode(n: i64, names: *i64, types: *i64, req: *i64, out: *u8) -> i64 { 27 var o: i64 = sc_w32(out, 0, n) 28 var i: i64=0 29 while i < n { 30 out[o]=types[i] as u8; o=o+1 31 out[o]=req[i] as u8; o=o+1 32 let nm: *u8 = (names[i]) as *u8; let nl: i64 = sc_slen(nm) 33 o = sc_w32(out, o, nl) 34 var k: i64=0; while k<nl { out[o]=nm[k]; o=o+1; k=k+1 } 35 i=i+1 36 } 37 return o 38} 39// decode into parallel arrays; returns field count. 40func sc_decode(b: *u8, out_names: *i64, out_types: *i64, out_req: *i64) -> i64 { 41 let n: i64 = sc_r32(b, 0); var o: i64 = 4 42 var i: i64=0 43 while i < n { 44 out_types[i] = b[o]; o=o+1 45 out_req[i] = b[o]; o=o+1 46 let nl: i64 = sc_r32(b, o); o=o+4 47 let nm: *u8 = sys_mmap(nl+1); var k: i64=0; while k<nl { nm[k]=b[o]; o=o+1; k=k+1 } nm[nl]=0 as u8 48 out_names[i] = nm as i64 49 i=i+1 50 } 51 return n 52} 53// is v2 a SAFE backward/forward evolution of v1? SC_SAFE / SC_REMOVED / SC_RETYPED / SC_NEWREQ. 54func sc_compat(n1: i64, names1: *i64, types1: *i64, n2: i64, names2: *i64, types2: *i64, req2: *i64) -> i64 { 55 var i: i64=0 56 while i < n1 { 57 let j: i64 = sc_find((names1[i]) as *u8, names2, n2) 58 if j < 0 { return SC_REMOVED } 59 if types2[j] != types1[i] { return SC_RETYPED } 60 i=i+1 61 } 62 i=0 63 while i < n2 { 64 let j: i64 = sc_find((names2[i]) as *u8, names1, n1) 65 if j < 0 { if req2[i] == SC_REQ { return SC_NEWREQ } } 66 i=i+1 67 } 68 return SC_SAFE 69}