code wiki / _hdl_build / nx_consul_kv_test.nx
nx_consul_kv_test.nx source
↩ module page · 60 lines · 4135 B
1// nx_consul_kv_test.nx -- CKVGATE: proves the sovereign Consul KV store + CAS. GREEN iff: a new key gets
2// version 1; updating it bumps to 2; get returns the current value; CAS with the CURRENT version applies and
3// bumps; CAS with a STALE version is REJECTED with NO change (the lock-safety property); delete removes the
4// key; a missing key reads -1. exit 0 on 7/7.
5import "nx_consul_kv.nx"
6import "nx_syscalls.nx"
7
8func kg_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
9func kg_num(v: i64) -> i64 { let b: *u8 = sys_mmap(28); var m: i64=v; if m<0 {m=0-m;sys_write(1,"-" as *u8,1)}; let t: *u8 = sys_mmap(28); var k: i64=0; if m==0 {t[0]=48;k=1}; while m>0 {t[k]=48+(m%10); m=m/10; k=k+1}; var i: i64=0; while i<k {b[i]=t[k-1-i]; i=i+1}; sys_write(1,b,k); return 0 }
10
11func main() -> i64 {
12 kg_puts("=== SOVEREIGN CONSUL KV STORE + COMPARE-AND-SWAP ===\n" as *u8)
13 let n: i64 = 8
14 let keys: *i64 = sys_mmap(64) as *i64
15 let vals: *i64 = sys_mmap(64) as *i64
16 let vers: *i64 = sys_mmap(64) as *i64
17 let present: *i64 = sys_mmap(64) as *i64
18 var z: i64 = 0; while z < n { present[z] = 0; z = z + 1 }
19 let neg1: i64 = 0 - 1
20 let k1: i64 = 111
21 let k2: i64 = 222
22
23 let v_put1: i64 = ckv_put(keys, vals, vers, present, n, k1, 1000) // create -> v1
24 let v_put2: i64 = ckv_put(keys, vals, vers, present, n, k1, 2000) // update -> v2
25 let idx1: i64 = ckv_get(keys, present, n, k1)
26 let getval: i64 = vals[idx1] // 2000
27
28 let cas_ok: i64 = ckv_cas(keys, vals, vers, present, n, k1, 3000, 2) // expected 2 == current -> apply, v3
29 let cas_ok_val: i64 = vals[idx1] // 3000
30 let cas_ok_ver: i64 = vers[idx1] // 3
31 let cas_stale: i64 = ckv_cas(keys, vals, vers, present, n, k1, 9999, 2) // expected 2 but now 3 -> conflict
32 let cas_stale_val: i64 = vals[idx1] // still 3000
33
34 ckv_delete(present, ckv_get(keys, present, n, k1))
35 let get_after_del: i64 = ckv_get(keys, present, n, k1) // -1
36 let get_missing: i64 = ckv_get(keys, present, n, k2) // -1 (never put)
37
38 kg_puts(" put1_ver=" as *u8); kg_num(v_put1); kg_puts(" put2_ver=" as *u8); kg_num(v_put2); kg_puts(" get=" as *u8); kg_num(getval)
39 kg_puts(" | cas_ok=" as *u8); kg_num(cas_ok); kg_puts(" val=" as *u8); kg_num(cas_ok_val); kg_puts(" ver=" as *u8); kg_num(cas_ok_ver)
40 kg_puts(" | cas_stale=" as *u8); kg_num(cas_stale); kg_puts(" val=" as *u8); kg_num(cas_stale_val)
41 kg_puts(" | after_del=" as *u8); kg_num(get_after_del); kg_puts(" missing=" as *u8); kg_num(get_missing); kg_puts("\n" as *u8)
42
43 let r: *i64 = sys_mmap(8*8) as *i64
44 r[0] = 0; if v_put1 == 1 { r[0] = 1 } // create -> version 1
45 r[1] = 0; if v_put2 == 2 { r[1] = 1 } // update -> version 2
46 r[2] = 0; if getval == 2000 { r[2] = 1 } // get returns current value
47 r[3] = 0; if cas_ok == 1 { if cas_ok_val == 3000 { if cas_ok_ver == 3 { r[3] = 1 } } } // CAS applies + bumps
48 r[4] = 0; if cas_stale == 0 { if cas_stale_val == 3000 { r[4] = 1 } } // stale CAS rejected, unchanged
49 r[5] = 0; if get_after_del == neg1 { r[5] = 1 } // delete removes
50 r[6] = 0; if get_missing == neg1 { r[6] = 1 } // missing key -> -1
51
52 var pass: i64 = 0; var i: i64 = 0
53 while i < 7 { pass = pass + r[i]; i = i + 1 }
54 kg_puts("----\n passed " as *u8); kg_num(pass); kg_puts("/7\n" as *u8)
55 if pass == 7 {
56 kg_puts("CKVGATE versioned_kv=1 modify_bumps_version=1 cas_applies_on_match=1 cas_rejects_stale=1 delete=1 missing=-1 exceed[sovereign Consul KV + compare-and-swap = the optimistic-concurrency primitive for distributed locks/leader-election; bits-up] verdict=GREEN\n" as *u8)
57 sys_exit(0); return 0
58 }
59 kg_puts("CKVGATE verdict=RED\n" as *u8); sys_exit(1); return 1
60}