code wiki / (root) / nx_pub_release_prepare_candidate_t256.nx

nx_pub_release_prepare_candidate_t256.nx source

↩ module page · 145 lines · 5491 B

1// Versioned release identity records in the existing publication store. No q-row rewrite. 2import "nx_seg_store.nx" 3 4const PR_OK: i64 = 0 5const PR_CREATED: i64 = 1 6const PR_INVALID: i64 = 2 7const PR_IO: i64 = 4 8const PR_CONFLICT: i64 = 8 9const PR_SHA_HEX: i64 = 64 10const PR_KEY_PREFIX: *u8 = "pub-release:" as *u8 11const PR_RECORD_PREFIX: *u8 = "NPR1\tregistered\t" as *u8 12 13func pr_path_ok(path: *u8) -> i64 { 14 let root: *u8 = "releases/" as *u8 15 var i: i64 = 0 16 while root[i] != (0 as u8) { 17 if path[i] != root[i] { return 0 } 18 i = i + 1 19 } 20 if path[i] == (0 as u8) { return 0 } 21 var segment: i64 = 0 22 while path[i] != (0 as u8) { 23 let ch: i64 = path[i] as i64 24 if ch == 47 { 25 if segment == 0 { return 0 } 26 segment = 0 27 } else { 28 if ch == 46 { 29 if segment == 0 { return 0 } 30 if path[i+1] == (46 as u8) { return 0 } 31 } else { 32 var allowed: i64 = 0 33 if ch >= 48 && ch <= 57 { allowed = 1 } 34 if ch >= 65 && ch <= 90 { allowed = 1 } 35 if ch >= 97 && ch <= 122 { allowed = 1 } 36 if ch == 45 || ch == 95 { allowed = 1 } 37 if allowed == 0 { return 0 } 38 } 39 segment = segment + 1 40 } 41 i = i + 1 42 } 43 return (segment > 0) as i64 44} 45func pr_hash_ok(hash: *u8) -> i64 { 46 if ss_len(hash) != PR_SHA_HEX { return 0 } 47 var i: i64 = 0 48 while i < PR_SHA_HEX { 49 let ch: i64 = hash[i] as i64 50 var ok: i64 = 0 51 if ch >= 48 && ch <= 57 { ok = 1 } 52 if ch >= 97 && ch <= 102 { ok = 1 } 53 if ok == 0 { return 0 } 54 i = i + 1 55 } 56 return 1 57} 58func pr_key(path: *u8) -> *u8 { 59 let key: *u8 = sys_mmap(ss_len(PR_KEY_PREFIX)+ss_len(path)+1) 60 let n: i64 = ss_cat(key,0,PR_KEY_PREFIX) 61 let end: i64 = ss_cat(key,n,path) 62 key[end] = 0 as u8 63 return key 64} 65func pr_record(hash: *u8) -> *u8 { 66 let rec: *u8 = sys_mmap(ss_len(PR_RECORD_PREFIX)+PR_SHA_HEX+1) 67 let n: i64 = ss_cat(rec,0,PR_RECORD_PREFIX) 68 let end: i64 = ss_cat(rec,n,hash) 69 rec[end] = 0 as u8 70 return rec 71} 72func pr_same(a: *u8, an: i64, b: *u8, bn: i64) -> i64 { 73 if an != bn { return 0 } 74 var i: i64 = 0 75 while i < an { if a[i] != b[i] { return 0 }; i = i + 1 } 76 return 1 77} 78func pr_check(prefix: *u8, path: *u8, hash: *u8) -> i64 { 79 if pr_path_ok(path) == 0 { return PR_INVALID } 80 if pr_hash_ok(hash) == 0 { return PR_INVALID } 81 let key: *u8 = pr_key(path) 82 let rec: *u8 = pr_record(hash) 83 let ptr: *i64 = sys_mmap(16) as *i64 84 let len: *i64 = sys_mmap(16) as *i64 85 let found: i64 = ss_get_idx_required(prefix,key,ptr,len) 86 if found == (0-2) { return PR_IO } 87 if found != 1 { return PR_CONFLICT } 88 if pr_same(ptr[0] as *u8,len[0],rec,ss_len(rec)) == 0 { return PR_CONFLICT } 89 return PR_OK 90} 91func pr_register(prefix: *u8, path: *u8, hash: *u8) -> i64 { 92 if pr_path_ok(path) == 0 { return PR_INVALID } 93 if pr_hash_ok(hash) == 0 { return PR_INVALID } 94 let generation: i64 = ss_max_segid(prefix) 95 // Never create an independent catalogue accidentally: require the existing publication plane. 96 let ptr: *i64 = sys_mmap(16) as *i64 97 let len: *i64 = sys_mmap(16) as *i64 98 if ss_get_idx_required(prefix,"q:n" as *u8,ptr,len) != 1 { return PR_IO } 99 let key: *u8 = pr_key(path) 100 let rec: *u8 = pr_record(hash) 101 let existing: i64 = ss_get_idx_required(prefix,key,ptr,len) 102 if existing == 1 { 103 if pr_same(ptr[0] as *u8,len[0],rec,ss_len(rec)) == 1 { return PR_OK } 104 return PR_CONFLICT 105 } 106 if existing == (0-2) { return PR_IO } 107 if existing != (0-1) { return PR_CONFLICT } 108 // Capacity is the actual serialized entry length plus the store's entry-header requirement. 109 let writer: *i64 = ss_begin_cap(ss_len(key)+ss_len(rec)+16) 110 if ss_add(writer,1,key,rec,ss_len(rec)) < 0 { return PR_IO } 111 let rc: i64 = ss_commit_cas(prefix,writer,ss_next_segid(prefix),generation) 112 if rc == SS_ERR_STALE { return PR_CONFLICT } 113 if rc != 0 { return PR_IO } 114 if pr_check(prefix,path,hash) != PR_OK { return PR_IO } 115 return PR_CREATED 116} 117 118// Detailed read-only observation for release preparation; legacy pr_check codes stay unchanged. 119const PR_MISSING: i64 = 3 120func pr_observe(prefix: *u8,path: *u8,hash: *u8) -> i64 { 121 if pr_path_ok(path)!=1||pr_hash_ok(hash)!=1{return PR_INVALID} 122 let keybytes:i64=ss_len(PR_KEY_PREFIX)+ss_len(path)+1 123 let recbytes:i64=ss_len(PR_RECORD_PREFIX)+PR_SHA_HEX+1 124 let ptr:*i64=sys_mmap_try(16) as *i64;let len:*i64=sys_mmap_try(16) as *i64 125 let key:*u8=sys_mmap_try(keybytes);let rec:*u8=sys_mmap_try(recbytes) 126 var rc:i64=PR_IO 127 if (ptr as i64)>0&&(len as i64)>0&&(key as i64)>0&&(rec as i64)>0 { 128 if ss_get_idx_required(prefix,"q:n",ptr,len)==1{ 129 let kp:i64=ss_cat(key,0,PR_KEY_PREFIX);key[ss_cat(key,kp,path)]=0 130 let rp:i64=ss_cat(rec,0,PR_RECORD_PREFIX);rec[ss_cat(rec,rp,hash)]=0 131 let found:i64=ss_get_idx_required(prefix,key,ptr,len) 132 rc=PR_CONFLICT 133 if found==(0-2){rc=PR_IO}else{ 134 if found==(0-1){rc=PR_MISSING}else{ 135 if found==1{if pr_same(ptr[0] as *u8,len[0],rec,ss_len(rec))==1{rc=PR_OK}} 136 } 137 } 138 } 139 } 140 if (key as i64)>0{if sys_munmap(key,keybytes)!=0{rc=PR_IO}} 141 if (rec as i64)>0{if sys_munmap(rec,recbytes)!=0{rc=PR_IO}} 142 if (ptr as i64)>0{if sys_munmap(ptr as *u8,16)!=0{rc=PR_IO}} 143 if (len as i64)>0{if sys_munmap(len as *u8,16)!=0{rc=PR_IO}} 144 return rc 145}