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}