code wiki / _hdl_build / nx_consul_kv.nx

nx_consul_kv.nx source

↩ module page · 40 lines · 2042 B

1// nx_consul_kv.nx -- sovereign KEY-VALUE store with COMPARE-AND-SWAP (HashiCorp Consul KV-class; CONSUL-002). 2// Each key carries a per-key version (Consul's ModifyIndex) that bumps on every modify. CAS applies a write 3// ONLY if the caller's expected version matches the current one (optimistic concurrency) -- this is the 4// primitive distributed LOCKS and leader-election are built on (a stale writer is rejected, never clobbers). 5// Pure logic over fixed-slot arrays. license_tier: ORIGINAL (composes into the sovereign-Consul arc) 6import "nx_syscalls.nx" 7 8// index of a present key, or -1. 9func ckv_get(keys: *i64, present: *i64, n: i64, key: i64) -> i64 { 10 var i: i64 = 0 11 while i < n { if present[i] == 1 { if keys[i] == key { return i } } i = i + 1 } 12 return 0 - 1 13} 14 15// create-or-update; bump the per-key version; return the new version (-1 if no free slot on create). 16func ckv_put(keys: *i64, vals: *i64, vers: *i64, present: *i64, n: i64, key: i64, val: i64) -> i64 { 17 let idx: i64 = ckv_get(keys, present, n, key) 18 if idx >= 0 { vals[idx] = val; vers[idx] = vers[idx] + 1; return vers[idx] } 19 var i: i64 = 0 20 while i < n { 21 if present[i] == 0 { present[i] = 1; keys[i] = key; vals[i] = val; vers[i] = 1; return 1 } 22 i = i + 1 23 } 24 return 0 - 1 25} 26 27// compare-and-swap: apply ONLY if current version == expected (expected==0 creates a missing key). 28// returns 1 = applied (version bumped), 0 = conflict (no change). The lock-safety primitive. 29func ckv_cas(keys: *i64, vals: *i64, vers: *i64, present: *i64, n: i64, key: i64, val: i64, expected: i64) -> i64 { 30 let idx: i64 = ckv_get(keys, present, n, key) 31 if idx < 0 { 32 if expected == 0 { if ckv_put(keys, vals, vers, present, n, key, val) > 0 { return 1 } return 0 } 33 return 0 34 } 35 if vers[idx] == expected { vals[idx] = val; vers[idx] = vers[idx] + 1; return 1 } 36 return 0 37} 38 39// delete a key by index (idempotent). 40func ckv_delete(present: *i64, idx: i64) -> i64 { if idx >= 0 { present[idx] = 0 } return 0 }