code wiki / (root) / nx_search_win_src.nx

nx_search_win_src.nx source

↩ module page · 102 lines · 4898 B

1// nx_search_win_src.nx -- Builds a minimal inverted index for three documents, supporting query lookup and ranking on Windows. 2const K_MAGIC_5381: i64 = 5381 3// nx_search_win_src.nx -- self-contained minimal inverted index for the PE keystone-linker (nx_pe_compile_win_index). 4// Uses ONLY sys_mmap / sys_write / sys_exit + main (the 3 syscalls the HAL thunks to HeapAlloc/WriteFile/ExitProcess). 5// Real token->doc-bitmap inverted index over 3 hardcoded docs + queries. The SAME index logic that runs on Linux, now 6// compiled to a native Windows PE = the multi-target / platform-independence proof. Zeroes its own table (HeapAlloc, 7// unlike Linux mmap, does NOT zero memory -- a portability must). Bodies of the 3 syscalls are overwritten by thunks. 8// license_tier: ORIGINAL 9 10func sys_mmap(size: i64) -> *u8 { return __syscall(9, 0, size, 3, 34, 0-1, 0) as *u8 } 11func sys_write(fd: i64, buf: *u8, n: i64) -> i64 { return __syscall(1, fd, buf as i64, n, 0, 0, 0) } 12func sys_exit(code: i64) -> i64 { return __syscall(60, code, 0, 0, 0, 0, 0) } 13 14const SLOTS: i64 = 256 15 16func swin_lc(c: i64) -> i64 { if c>=65 { if c<=90 { return c+32 } } return c } 17func swin_is_tok(c: i64) -> i64 { if c>=97 { if c<=122 { return 1 } } if c>=65 { if c<=90 { return 1 } } if c>=48 { if c<=57 { return 1 } } return 0 } 18func swin_hash(b: *u8, s: i64, e: i64) -> i64 { var h: i64=K_MAGIC_5381; var i: i64=s; while i<e { h=h*33 + swin_lc(b[i] as i64); i=i+1 } if h<0 { h=0-h } return h } 19 20func swin_add(tbl: *i64, hsh: i64, doc: i64) -> i64 { 21 var slot: i64 = hsh % SLOTS; var probe: i64 = 0 22 while probe < SLOTS { 23 let base: i64 = slot*2 24 if tbl[base]==0 { tbl[base]=hsh; tbl[base+1]=1<<doc; return 1 } 25 if tbl[base]==hsh { tbl[base+1] = tbl[base+1] | (1<<doc); return 1 } 26 slot = (slot+1) % SLOTS; probe = probe+1 27 } 28 return 0 29} 30func swin_get(tbl: *i64, hsh: i64) -> i64 { 31 var slot: i64 = hsh % SLOTS; var probe: i64 = 0 32 while probe < SLOTS { 33 let base: i64 = slot*2 34 if tbl[base]==0 { return 0 } 35 if tbl[base]==hsh { return tbl[base+1] } 36 slot = (slot+1) % SLOTS; probe = probe+1 37 } 38 return 0 39} 40func swin_doc(tbl: *i64, s: *u8, doc: i64) -> i64 { 41 var n: i64=0; while s[n]!=(0 as u8) { n=n+1 } 42 var i: i64=0 43 while i < n { 44 if swin_is_tok(s[i] as i64)==0 { i=i+1 } else { 45 let st: i64=i; var go: i64=1 46 while go==1 { if i<n { if swin_is_tok(s[i] as i64)==1 { i=i+1 } else { go=0 } } else { go=0 } } 47 swin_add(tbl, swin_hash(s, st, i), doc) 48 } 49 } 50 return 0 51} 52func swin_report(tbl: *i64, term: *u8) -> i64 { 53 var tn: i64=0; while term[tn]!=(0 as u8){tn=tn+1} 54 let bits: i64 = swin_get(tbl, swin_hash(term, 0, tn)) 55 sys_write(1, term, tn); sys_write(1, " -> docs:" as *u8, 9) 56 let ob: *u8 = sys_mmap(8) 57 var d: i64=0 58 while d<3 { if ((bits>>d)&1)==1 { ob[0]=32 as u8; ob[1]=(48+d) as u8; sys_write(1, ob, 2) } d=d+1 } 59 sys_write(1, "\n" as *u8, 1) 60 return 0 61} 62 63// RANK: score each doc = number of query terms it contains; print scores + the top doc. Proves ranking runs native. 64func swin_rank(tbl: *i64, terms: *i64, nterms: i64) -> i64 { 65 let score: *i64 = sys_mmap(3*8) as *i64 66 var d: i64=0; while d<3 { score[d]=0; d=d+1 } 67 var q: i64=0 68 while q<nterms { 69 let term: *u8 = terms[q] as *u8 70 var tn: i64=0; while term[tn]!=(0 as u8){tn=tn+1} 71 let bits: i64 = swin_get(tbl, swin_hash(term,0,tn)) 72 d=0; while d<3 { if ((bits>>d)&1)==1 { score[d]=score[d]+1 } d=d+1 } 73 q=q+1 74 } 75 sys_write(1, "rank scores doc0/1/2:" as *u8, 21) 76 d=0; while d<3 { let ob: *u8=sys_mmap(4); ob[0]=32 as u8; ob[1]=(48+score[d]) as u8; sys_write(1,ob,2); d=d+1 } 77 sys_write(1, "\n" as *u8, 1) 78 var top: i64=0; d=1; while d<3 { if score[d]>score[top] { top=d } d=d+1 } 79 sys_write(1, "top doc = " as *u8, 10); let tb: *u8=sys_mmap(4); tb[0]=(48+top) as u8; sys_write(1,tb,1); sys_write(1,"\n" as *u8,1) 80 return top 81} 82 83func main() -> i64 { 84 let tbl: *i64 = sys_mmap(SLOTS*16) as *i64 85 var z: i64=0; while z < SLOTS*2 { tbl[z]=0; z=z+1 } // HeapAlloc does NOT zero -- do it ourselves (portability) 86 swin_doc(tbl, "sovereign crawler index" as *u8, 0) 87 swin_doc(tbl, "inverted postings list" as *u8, 1) 88 swin_doc(tbl, "pagerank damping authority" as *u8, 2) 89 sys_write(1, "NX-SEARCH-INDEX (native PE):\n" as *u8, 28) 90 swin_report(tbl, "crawler" as *u8) 91 swin_report(tbl, "postings" as *u8) 92 swin_report(tbl, "damping" as *u8) 93 swin_report(tbl, "zznope" as *u8) 94 // RANKED multi-term query "crawler index" -> doc0 has both -> top 95 let terms: *i64 = sys_mmap(4*8) as *i64 96 terms[0] = "crawler" as *u8 as i64 97 terms[1] = "index" as *u8 as i64 98 sys_write(1, "-- ranked query 'crawler index' --\n" as *u8, 35) 99 swin_rank(tbl, terms, 2) 100 sys_exit(0) 101 return 0 102}