code wiki / _hdl_build / nx_search_race.nx
nx_search_race.nx source
↩ module page · 255 lines · 10966 B
1// nx_search_race.nx -- IM6b: THE BEAT-FTS5 SEARCH RACE (the full-text-search
2// EXCEED measurement on the REAL unified team-log corpus).
3//
4// Two lanes, SAME input (pm_plan_durable.log + cap_registry_durable.log,
5// unique non-empty lines), SAME 9-query set (6 terms + 3 ANDs) x 200
6// iterations, each lane self-timing ONLY its engine work:
7// SOV lane: /tmp/nx_race_search_worker.sov.elf (chunked fsync'd commits
8// w/ .keys+.terms/.post; handle + postings queries)
9// FTS5 lane: python3 sqlite3 FTS5 (the incumbent full-text engine; run as
10// an EXTERNAL COMPETITOR PROCESS, harness .py written to /tmp at
11// runtime -- the repo stays pure NishiLang)
12//
13// Verdict law: numbers are MEASURED and logged win or lose; every per-query
14// COUNT must match between lanes or the race is INVALID (correctness before
15// speed). Exit 0 only on SOV-WINS-BOTH. Durable: infomgmt_race.log.
16// license_tier: ORIGINAL
17
18import "nx_syscalls.nx"
19import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
20const K_MAGIC_8192: i64 = 8192
21const K_MAGIC_8000: i64 = 8000
22
23func sx_p(s: *u8) -> i64 {
24 var n: i64 = 0
25 while s[n] != (0 as u8) { n = n + 1 }
26 sys_write(1, s, n)
27 return 0
28}
29
30func sx_fp(fd: i64, s: *u8) -> i64 {
31 var n: i64 = 0
32 while s[n] != (0 as u8) { n = n + 1 }
33 sys_write(fd, s, n)
34 return 0
35}
36
37// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
38// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
39// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
40// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
41func sx_fn(fd: i64, v: i64) -> i64 { nxi_fd(fd, v); return 0 }
42
43func sx_cat(dst: *u8, off: i64, s: *u8) -> i64 {
44 var i: i64 = 0
45 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 }
46 return off + i
47}
48
49func sx_catn(dst: *u8, off: i64, v: i64) -> i64 {
50 var m: i64 = v
51 var o: i64 = off
52 let t: *u8 = sys_mmap(28)
53 var k: i64 = 0
54 if m == 0 { t[0] = 48 as u8; k = 1 }
55 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
56 var i: i64 = 0
57 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 }
58 return o + k
59}
60
61func sx_run(path: *u8, a1: *u8, a2: *u8, a3: *u8, outpath: *u8) -> i64 {
62 let pid: i64 = sys_fork()
63 if pid == 0 {
64 let ofd: i64 = sys_openat_wr(outpath, 0x1a4)
65 if ofd >= 0 { sys_dup3(ofd, 1, 0) }
66 let dn: i64 = sys_openat_wr("/dev/null" as *u8, 0x1a4)
67 if dn >= 0 { sys_dup3(dn, 2, 0) }
68 let argv: *i64 = sys_mmap(8 * 6) as *i64
69 argv[0] = path as i64
70 var na: i64 = 1
71 if (a1 as i64) != 0 { argv[na] = a1 as i64; na = na + 1 }
72 if (a2 as i64) != 0 { argv[na] = a2 as i64; na = na + 1 }
73 if (a3 as i64) != 0 { argv[na] = a3 as i64; na = na + 1 }
74 argv[na] = 0
75 let envp: *i64 = sys_mmap(16) as *i64
76 envp[0] = 0
77 sys_execve(path, argv, envp)
78 sys_exit(127)
79 }
80 let st: *i64 = sys_mmap(16) as *i64
81 sys_wait4(pid, st, 0)
82 return st[0]
83}
84
85func sx_num_after(path: *u8, pat: *u8) -> i64 {
86 let fd: i64 = sys_openat_rd(path)
87 if fd < 0 { return 0 - 1 }
88 let b: *u8 = sys_mmap(K_MAGIC_8192)
89 let n: i64 = sys_read(fd, b, K_MAGIC_8000)
90 sys_close(fd)
91 if n <= 0 { return 0 - 1 }
92 var pl: i64 = 0
93 while pat[pl] != (0 as u8) { pl = pl + 1 }
94 var i: i64 = 0
95 while i + pl <= n {
96 var hit: i64 = 1
97 var k: i64 = 0
98 while k < pl {
99 if hit == 1 { if b[i + k] != pat[k] { hit = 0 } }
100 k = k + 1
101 }
102 if hit == 1 {
103 var v: i64 = 0
104 var p: i64 = i + pl
105 var any: i64 = 0
106 var go: i64 = 1
107 while go == 1 {
108 if p >= n { go = 0 }
109 if go == 1 {
110 let c: i64 = b[p]
111 if c >= 48 { if c <= 57 { v = v * 10 + (c - 48); any = 1; p = p + 1 } else { go = 0 } } else { go = 0 }
112 }
113 }
114 if any == 1 { return v }
115 return 0 - 1
116 }
117 i = i + 1
118 }
119 return 0 - 1
120}
121
122// the FTS5 competitor harness (.py) -- /tmp only, never the repo
123func sx_write_py(path: *u8) -> i64 {
124 let fd: i64 = sys_openat_wr(path, 0x1a4)
125 if fd < 0 { return 0 - 1 }
126 sx_fp(fd, "import sqlite3, time, sys\n" as *u8)
127 sx_fp(fd, "mode=sys.argv[1]; db=sys.argv[2]\n" as *u8)
128 sx_fp(fd, "docs=[]; seen=set()\n" as *u8)
129 sx_fp(fd, "for f in ('knowledge/status/pm_plan_durable.log','knowledge/status/cap_registry_durable.log'):\n" as *u8)
130 sx_fp(fd, " for L in open(f, encoding='utf-8', errors='replace'):\n" as *u8)
131 sx_fp(fd, " L=L.rstrip('\\n')\n" as *u8)
132 sx_fp(fd, " if L=='' or L in seen: continue\n" as *u8)
133 sx_fp(fd, " seen.add(L); docs.append(L)\n" as *u8)
134 sx_fp(fd, "QT=['infomgmt','compaction','postings','sovereign','capreg','gate']\n" as *u8)
135 sx_fp(fd, "QA=[('infomgmt','postings'),('sovereign','gate'),('compaction','archive')]\n" as *u8)
136 sx_fp(fd, "if mode=='write':\n" as *u8)
137 sx_fp(fd, " t0=time.monotonic_ns()\n" as *u8)
138 sx_fp(fd, " c=sqlite3.connect(db)\n" as *u8)
139 sx_fp(fd, " c.execute('CREATE VIRTUAL TABLE docs USING fts5(line)')\n" as *u8)
140 sx_fp(fd, " cur=c.cursor()\n" as *u8)
141 sx_fp(fd, " for d in docs: cur.execute('INSERT INTO docs VALUES(?)',(d,))\n" as *u8)
142 sx_fp(fd, " c.commit(); c.close()\n" as *u8)
143 sx_fp(fd, " t1=time.monotonic_ns()\n" as *u8)
144 sx_fp(fd, " print('SQLW us=%d count=%d' % ((t1-t0)//1000, len(docs)))\n" as *u8)
145 sx_fp(fd, "else:\n" as *u8)
146 sx_fp(fd, " t0=time.monotonic_ns()\n" as *u8)
147 sx_fp(fd, " c=sqlite3.connect(db)\n" as *u8)
148 sx_fp(fd, " qc=[0]*9\n" as *u8)
149 sx_fp(fd, " for it in range(200):\n" as *u8)
150 sx_fp(fd, " for i,t in enumerate(QT):\n" as *u8)
151 sx_fp(fd, " qc[i]=c.execute('SELECT count(*) FROM docs WHERE docs MATCH ?',(t,)).fetchone()[0]\n" as *u8)
152 sx_fp(fd, " for i,(a,b) in enumerate(QA):\n" as *u8)
153 sx_fp(fd, " qc[6+i]=c.execute('SELECT count(*) FROM docs WHERE docs MATCH ?',(a+' AND '+b,)).fetchone()[0]\n" as *u8)
154 sx_fp(fd, " c.close()\n" as *u8)
155 sx_fp(fd, " t1=time.monotonic_ns()\n" as *u8)
156 sx_fp(fd, " print('SQLQ us=%d %s count=%d' % ((t1-t0)//1000, ' '.join('q%d=%d'%(i,v) for i,v in enumerate(qc)), len(docs)))\n" as *u8)
157 sys_close(fd)
158 return 0
159}
160
161func main() -> i64 {
162 sx_p("=== IM6b SEARCH RACE: sovereign postings vs sqlite FTS5 (team-log corpus, 9 queries x 200) ===\n" as *u8)
163 let wpath: *u8 = "/tmp/nx_race_search_worker.sov.elf" as *u8
164 let probe: i64 = sys_openat_rd(wpath)
165 if probe >= 0 { sys_close(probe) } else {
166 sx_run("_offc/nx_sov_build_run.elf" as *u8, "nx_race_search_worker" as *u8, 0 as *u8, 0 as *u8, "/tmp/srace_build.out" as *u8)
167 }
168
169 let id: i64 = sys_now_us()
170 let sovpfx: *u8 = sys_mmap(128)
171 var o: i64 = 0
172 o = sx_cat(sovpfx, o, "/tmp/srsov" as *u8)
173 o = sx_catn(sovpfx, o, id)
174 o = sx_cat(sovpfx, o, "-" as *u8)
175 sovpfx[o] = 0 as u8
176 let dbp: *u8 = sys_mmap(128)
177 o = 0
178 o = sx_cat(dbp, o, "/tmp/srsql" as *u8)
179 o = sx_catn(dbp, o, id)
180 o = sx_cat(dbp, o, ".db" as *u8)
181 dbp[o] = 0 as u8
182
183 if sx_write_py("/tmp/srace_fts5.py" as *u8) != 0 { sx_p(" py harness write FAILED\n" as *u8); return 1 }
184
185 sx_run(wpath, "write" as *u8, sovpfx, 0 as *u8, "/tmp/srace_sw.out" as *u8)
186 sx_run(wpath, "query" as *u8, sovpfx, 0 as *u8, "/tmp/srace_sq.out" as *u8)
187 let py: *u8 = "/usr/bin/python3" as *u8
188 sx_run(py, "/tmp/srace_fts5.py" as *u8, "write" as *u8, dbp, "/tmp/srace_qw.out" as *u8)
189 sx_run(py, "/tmp/srace_fts5.py" as *u8, "query" as *u8, dbp, "/tmp/srace_qq.out" as *u8)
190
191 let sw: i64 = sx_num_after("/tmp/srace_sw.out" as *u8, "SOVW us=" as *u8)
192 let swc: i64 = sx_num_after("/tmp/srace_sw.out" as *u8, "count=" as *u8)
193 let sq: i64 = sx_num_after("/tmp/srace_sq.out" as *u8, "SOVQ us=" as *u8)
194 let sqc: i64 = sx_num_after("/tmp/srace_sq.out" as *u8, "count=" as *u8)
195 let qw: i64 = sx_num_after("/tmp/srace_qw.out" as *u8, "SQLW us=" as *u8)
196 let qwc: i64 = sx_num_after("/tmp/srace_qw.out" as *u8, "count=" as *u8)
197 let qq: i64 = sx_num_after("/tmp/srace_qq.out" as *u8, "SQLQ us=" as *u8)
198 let qqc: i64 = sx_num_after("/tmp/srace_qq.out" as *u8, "count=" as *u8)
199
200 // per-query correctness cross-check (q0..q8 must match pairwise)
201 var counts_ok: i64 = 0
202 if swc > 0 { if swc == sqc { if swc == qwc { if swc == qqc { counts_ok = 1 } } } }
203 let pat: *u8 = sys_mmap(16)
204 var qi: i64 = 0
205 while qi < 9 {
206 var po: i64 = 0
207 po = sx_cat(pat, po, "q" as *u8)
208 po = sx_catn(pat, po, qi)
209 po = sx_cat(pat, po, "=" as *u8)
210 pat[po] = 0 as u8
211 let a: i64 = sx_num_after("/tmp/srace_sq.out" as *u8, pat)
212 let b: i64 = sx_num_after("/tmp/srace_qq.out" as *u8, pat)
213 if a < 0 { counts_ok = 0 }
214 if a != b { counts_ok = 0 }
215 qi = qi + 1
216 }
217 var win_w: i64 = 0
218 if sw >= 0 { if qw >= 0 { if sw <= qw { win_w = 1 } } }
219 var win_q: i64 = 0
220 if sq >= 0 { if qq >= 0 { if sq <= qq { win_q = 1 } } }
221
222 let lfd: i64 = sys_openat_append("knowledge/status/infomgmt_race.log" as *u8, 0x1a4)
223 var fdi: i64 = 0
224 while fdi < 2 {
225 var fd: i64 = 1
226 if fdi == 1 { fd = lfd }
227 if fd > 0 {
228 sx_fp(fd, "RACE epoch=" as *u8)
229 sx_fn(fd, sys_now_realtime_sec())
230 sx_fp(fd, " workload=logsearch docs=" as *u8)
231 sx_fn(fd, swc)
232 sx_fp(fd, " sov_index_us=" as *u8)
233 sx_fn(fd, sw)
234 sx_fp(fd, " fts5_index_us=" as *u8)
235 sx_fn(fd, qw)
236 sx_fp(fd, " sov_query_us=" as *u8)
237 sx_fn(fd, sq)
238 sx_fp(fd, " fts5_query_us=" as *u8)
239 sx_fn(fd, qq)
240 sx_fp(fd, " counts_ok=" as *u8)
241 sx_fn(fd, counts_ok)
242 if counts_ok == 1 {
243 if win_w == 1 { if win_q == 1 { sx_fp(fd, " verdict=SOV-WINS-BOTH\n" as *u8) } }
244 if win_w == 1 { if win_q == 0 { sx_fp(fd, " verdict=MIXED-QUERY-LOSS (optimization rung: bitpack/FST dict + segment merge)\n" as *u8) } }
245 if win_w == 0 { if win_q == 1 { sx_fp(fd, " verdict=MIXED-INDEX-LOSS (optimization rung: single-segment bulk build + batch fsync)\n" as *u8) } }
246 if win_w == 0 { if win_q == 0 { sx_fp(fd, " verdict=SOV-LOSES-BOTH (file defect: slow is a bug)\n" as *u8) } }
247 }
248 if counts_ok != 1 { sx_fp(fd, " verdict=INVALID (counts disagree -- correctness before speed)\n" as *u8) }
249 }
250 fdi = fdi + 1
251 }
252 if lfd > 0 { sys_close(lfd) }
253 if counts_ok == 1 { if win_w == 1 { if win_q == 1 { return 0 } } }
254 return 1
255}