nx_sov_ledger.nx source
↩ module page · 82 lines · 3926 B
1// nx_sov_ledger.nx -- CANONICAL generic sovereign ledger on nx_seg_store. The DRY primitive that makes
2// "sovereign is as easy as a TSV" and kills the FRICTION root-cause of the flat-file habit.
3//
4// WHY THIS EXISTS (census 2026-07-14, runtime+_hdl_build/16029 .nx): ~599 organs write .tsv, ~1407 .log,
5// ~965 .txt for INTERNAL state vs only 324 seg_store adopters -- a ~10:1 flat-file default. Root cause is
6// not a missing store (nx_seg_store has time-travel history + compaction + postings = SOTA) but (a) no
7// enforcement sensor and (b) writing a TSV is 3 lines while seg_store means begin/add/commit + segid
8// discipline + a reader. This lib collapses that to one call. Dependency-light (seg_store + syscalls ONLY)
9// so ANY organ can adopt without dragging a domain stack.
10//
11// SOVEREIGN RECORD FORMAT (not burdened by others' non-SOTA decisions): typed BINARY records -- n i64 stored
12// as raw 8n little-endian bytes, NO tab/comma delimiters, NO stringly-typed parsing. (Even seg_store adopters
13// like nx_seedlib still pack tab bytes into the value; this is the fix for that too.)
14//
15// sov_put(prefix,key,val,vlen) KV put, idempotent latest-wins, segid=sys_now_us() (per-op-in-loop
16// safe -- ms collides & silently drops a record, [[reference-segstore-segid-use-now-us]])
17// sov_has(prefix,key) 1/0 existence (replaces "does <file>.tsv exist" resume checks)
18// sov_get(prefix,key,ptrout,lenout) newest value (zero-copy ptr into the store map)
19// sov_get_copy(prefix,key,out,cap) newest value copied into out (aligned); returns len or -1
20// sov_put_ints(prefix,key,vals,n) typed record: n i64 -> raw 8n bytes
21// sov_get_ints(prefix,key,out,maxn) read them back -> count, or -1 if absent (never fabricated)
22// license_tier: ORIGINAL
23import "nx_seg_store.nx"
24import "nx_syscalls.nx"
25
26func sov_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
27
28// KV put: idempotent latest-wins, unique microsecond segid (never loses a record in a tight loop).
29func sov_put(prefix: *u8, key: *u8, val: *u8, vlen: i64) -> i64 {
30 let w: *i64 = ss_begin()
31 ss_add(w, 1, key, val, vlen)
32 ss_commit(prefix, w, sys_now_us())
33 return 0
34}
35
36func sov_put_str(prefix: *u8, key: *u8, val: *u8) -> i64 {
37 return sov_put(prefix, key, val, sov_slen(val))
38}
39
40func sov_has(prefix: *u8, key: *u8) -> i64 {
41 let pq: *i64 = sys_mmap(16) as *i64
42 let lq: *i64 = sys_mmap(16) as *i64
43 if ss_get(prefix, key, pq, lq) == 1 { return 1 }
44 return 0
45}
46
47func sov_get(prefix: *u8, key: *u8, ptrout: *i64, lenout: *i64) -> i64 {
48 return ss_get(prefix, key, ptrout, lenout)
49}
50
51// copy newest value into out[0..cap); returns byte length, or -1 if absent.
52func sov_get_copy(prefix: *u8, key: *u8, out: *u8, cap: i64) -> i64 {
53 let pq: *i64 = sys_mmap(16) as *i64
54 let lq: *i64 = sys_mmap(16) as *i64
55 if ss_get(prefix, key, pq, lq) != 1 { return 0 - 1 }
56 let src: *u8 = pq[0] as *u8
57 var len: i64 = lq[0]
58 if len > cap { len = cap }
59 var i: i64 = 0
60 while i < len { out[i] = src[i]; i = i + 1 }
61 return len
62}
63
64// typed record: store n i64 as raw 8n bytes (sovereign binary, no delimiters).
65func sov_put_ints(prefix: *u8, key: *u8, vals: *i64, n: i64) -> i64 {
66 return sov_put(prefix, key, vals as *u8, n * 8)
67}
68
69// read the typed int record back into out[0..maxn); returns count, or -1 if absent (never fabricated).
70func sov_get_ints(prefix: *u8, key: *u8, out: *i64, maxn: i64) -> i64 {
71 let pq: *i64 = sys_mmap(16) as *i64
72 let lq: *i64 = sys_mmap(16) as *i64
73 if ss_get(prefix, key, pq, lq) != 1 { return 0 - 1 }
74 let src: *u8 = pq[0] as *u8
75 let len: i64 = lq[0]
76 var cnt: i64 = len / 8
77 if cnt > maxn { cnt = maxn }
78 let dst: *u8 = out as *u8
79 var i: i64 = 0
80 while i < cnt * 8 { dst[i] = src[i]; i = i + 1 }
81 return cnt
82}