aifastdb 3.10.5 → 3.10.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/aifastdb.node +0 -0
  2. package/aifastdb.win32-x64-msvc.node +0 -0
  3. package/dist/concurrent-document-store.d.ts +4 -0
  4. package/dist/concurrent-document-store.d.ts.map +1 -1
  5. package/dist/concurrent-document-store.js +6 -0
  6. package/dist/concurrent-document-store.js.map +1 -1
  7. package/dist/find-async-baseline.d.ts +33 -0
  8. package/dist/find-async-baseline.d.ts.map +1 -0
  9. package/dist/find-async-baseline.js +424 -0
  10. package/dist/find-async-baseline.js.map +1 -0
  11. package/dist/find-async-bench.d.ts +22 -0
  12. package/dist/find-async-bench.d.ts.map +1 -0
  13. package/dist/find-async-bench.js +322 -0
  14. package/dist/find-async-bench.js.map +1 -0
  15. package/dist/find-async-verify.d.ts +23 -0
  16. package/dist/find-async-verify.d.ts.map +1 -0
  17. package/dist/find-async-verify.js +286 -0
  18. package/dist/find-async-verify.js.map +1 -0
  19. package/dist/hnsw-insert-profile-verify.d.ts +35 -0
  20. package/dist/hnsw-insert-profile-verify.d.ts.map +1 -0
  21. package/dist/hnsw-insert-profile-verify.js +250 -0
  22. package/dist/hnsw-insert-profile-verify.js.map +1 -0
  23. package/dist/micro-batcher-benchmark.d.ts +3 -0
  24. package/dist/micro-batcher-benchmark.d.ts.map +1 -0
  25. package/dist/micro-batcher-benchmark.js +296 -0
  26. package/dist/micro-batcher-benchmark.js.map +1 -0
  27. package/dist/micro-batcher.d.ts +97 -0
  28. package/dist/micro-batcher.d.ts.map +1 -0
  29. package/dist/micro-batcher.js +77 -0
  30. package/dist/micro-batcher.js.map +1 -0
  31. package/dist/native.d.ts +71 -0
  32. package/dist/native.d.ts.map +1 -1
  33. package/dist/native.js +6 -1
  34. package/dist/native.js.map +1 -1
  35. package/dist/phase-387-reproducibility-audit.d.ts +3 -0
  36. package/dist/phase-387-reproducibility-audit.d.ts.map +1 -0
  37. package/dist/phase-387-reproducibility-audit.js +236 -0
  38. package/dist/phase-387-reproducibility-audit.js.map +1 -0
  39. package/dist/phase-390-baseline-multiseed.d.ts +3 -0
  40. package/dist/phase-390-baseline-multiseed.d.ts.map +1 -0
  41. package/dist/phase-390-baseline-multiseed.js +241 -0
  42. package/dist/phase-390-baseline-multiseed.js.map +1 -0
  43. package/dist/phase-390-t2-mb-grid-sweep.d.ts +3 -0
  44. package/dist/phase-390-t2-mb-grid-sweep.d.ts.map +1 -0
  45. package/dist/phase-390-t2-mb-grid-sweep.js +291 -0
  46. package/dist/phase-390-t2-mb-grid-sweep.js.map +1 -0
  47. package/dist/read-profiler-verify.js +236 -1
  48. package/dist/read-profiler-verify.js.map +1 -1
  49. package/dist/remember-many-spawn-benchmark.d.ts +3 -0
  50. package/dist/remember-many-spawn-benchmark.d.ts.map +1 -0
  51. package/dist/remember-many-spawn-benchmark.js +163 -0
  52. package/dist/remember-many-spawn-benchmark.js.map +1 -0
  53. package/dist/remember-spawn-benchmark.d.ts +3 -0
  54. package/dist/remember-spawn-benchmark.d.ts.map +1 -0
  55. package/dist/remember-spawn-benchmark.js +230 -0
  56. package/dist/remember-spawn-benchmark.js.map +1 -0
  57. package/dist/remember-spawn-receipt-benchmark.d.ts +3 -0
  58. package/dist/remember-spawn-receipt-benchmark.d.ts.map +1 -0
  59. package/dist/remember-spawn-receipt-benchmark.js +266 -0
  60. package/dist/remember-spawn-receipt-benchmark.js.map +1 -0
  61. package/dist/sgv2-async-verify.d.ts +17 -0
  62. package/dist/sgv2-async-verify.d.ts.map +1 -0
  63. package/dist/sgv2-async-verify.js +217 -0
  64. package/dist/sgv2-async-verify.js.map +1 -0
  65. package/dist/social-graph-v2-read-benchmark.d.ts +11 -2
  66. package/dist/social-graph-v2-read-benchmark.d.ts.map +1 -1
  67. package/dist/social-graph-v2-read-benchmark.js +145 -3
  68. package/dist/social-graph-v2-read-benchmark.js.map +1 -1
  69. package/dist/social-graph-v2.d.ts +65 -4
  70. package/dist/social-graph-v2.d.ts.map +1 -1
  71. package/dist/social-graph-v2.js +72 -6
  72. package/dist/social-graph-v2.js.map +1 -1
  73. package/package.json +1 -1
@@ -0,0 +1,322 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * phase-380/T380.4 (E380.C) — concurrent throughput e2e benchmark for the
5
+ * 5 new NAPI async wrappers (CDS findByTagAsync / findByMetadataAsync,
6
+ * SGV2 getTagMembersAsync / listTagsAsync / getPersonsByAttributeAsync).
7
+ *
8
+ * For each path we run:
9
+ * * sync sequential (for-loop, sync API)
10
+ * * async sequential (for-loop, async API at concurrency=1) -- spawn-overhead floor
11
+ * * async concurrent (Promise.all=N, async API)
12
+ *
13
+ * Decision gates (autoresearch):
14
+ * H-A1 (per-path concurrent lift): concurrent / sync >= 1.5x
15
+ * H-C (no single-call regression): seq async / sync sequential <= 5x
16
+ *
17
+ * Run after `npx tsc`:
18
+ * node packages/node/dist/find-async-bench.js \
19
+ * [--cdsDocs=20000] [--sgv2Persons=5000] [--sgv2Friends=20000] \
20
+ * [--scanOps=2000] [--concurrency=64]
21
+ */
22
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ var desc = Object.getOwnPropertyDescriptor(m, k);
25
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
26
+ desc = { enumerable: true, get: function() { return m[k]; } };
27
+ }
28
+ Object.defineProperty(o, k2, desc);
29
+ }) : (function(o, m, k, k2) {
30
+ if (k2 === undefined) k2 = k;
31
+ o[k2] = m[k];
32
+ }));
33
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
34
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
35
+ }) : function(o, v) {
36
+ o["default"] = v;
37
+ });
38
+ var __importStar = (this && this.__importStar) || (function () {
39
+ var ownKeys = function(o) {
40
+ ownKeys = Object.getOwnPropertyNames || function (o) {
41
+ var ar = [];
42
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
43
+ return ar;
44
+ };
45
+ return ownKeys(o);
46
+ };
47
+ return function (mod) {
48
+ if (mod && mod.__esModule) return mod;
49
+ var result = {};
50
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
51
+ __setModuleDefault(result, mod);
52
+ return result;
53
+ };
54
+ })();
55
+ Object.defineProperty(exports, "__esModule", { value: true });
56
+ const fs = __importStar(require("fs"));
57
+ const os = __importStar(require("os"));
58
+ const path = __importStar(require("path"));
59
+ const concurrent_document_store_1 = require("./concurrent-document-store");
60
+ const social_graph_v2_1 = require("./social-graph-v2");
61
+ function parseArgs() {
62
+ const cpuCount = os.cpus().length;
63
+ const args = new Map();
64
+ for (const raw of process.argv.slice(2)) {
65
+ if (!raw.startsWith('--'))
66
+ continue;
67
+ const [k, v] = raw.slice(2).split('=', 2);
68
+ args.set(k, v ?? 'true');
69
+ }
70
+ const num = (key, def) => {
71
+ const v = args.get(key);
72
+ if (!v)
73
+ return def;
74
+ const n = Number.parseInt(v, 10);
75
+ return Number.isFinite(n) && n > 0 ? n : def;
76
+ };
77
+ return {
78
+ cdsDocs: num('cdsDocs', 20000),
79
+ sgv2Persons: num('sgv2Persons', 5000),
80
+ sgv2Friends: num('sgv2Friends', 20000),
81
+ scanOps: num('scanOps', 2000),
82
+ concurrency: num('concurrency', 64),
83
+ shardCount: num('shards', Math.max(4, Math.min(cpuCount, 32))),
84
+ };
85
+ }
86
+ function makeTempDir(prefix) {
87
+ return fs.mkdtempSync(path.join(os.tmpdir(), prefix));
88
+ }
89
+ function cleanupDir(dir) {
90
+ try {
91
+ fs.rmSync(dir, { recursive: true, force: true });
92
+ }
93
+ catch {
94
+ /* swallow */
95
+ }
96
+ }
97
+ function fmt(n) {
98
+ return n.toLocaleString('en-US', { maximumFractionDigits: 1 });
99
+ }
100
+ const TAG_POOL = ['bench', 'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 'eta'];
101
+ function makeDoc(index) {
102
+ return {
103
+ id: `doc-${index}`,
104
+ content: `phase-380 bench payload #${index}`,
105
+ tags: [TAG_POOL[index % TAG_POOL.length], TAG_POOL[(index * 3 + 1) % TAG_POOL.length]],
106
+ docType: index % 2 === 0 ? 'note' : 'report',
107
+ importance: (index % 100) / 100,
108
+ metadata: {
109
+ source: `bench-${index % 16}`,
110
+ bucket: index % 64,
111
+ priority: 1 + (index % 5),
112
+ active: index % 2 === 0,
113
+ },
114
+ };
115
+ }
116
+ function sleep(ms) {
117
+ return new Promise((resolve) => setTimeout(resolve, ms));
118
+ }
119
+ async function waitForWrites(store, expected, timeoutMs = 30000) {
120
+ const deadline = performance.now() + timeoutMs;
121
+ while (performance.now() < deadline) {
122
+ if (store.metrics().successfulWrites >= expected)
123
+ return;
124
+ await sleep(1);
125
+ }
126
+ }
127
+ async function seedCds(store, total) {
128
+ const batchSize = 2000;
129
+ for (let s = 0; s < total; s += batchSize) {
130
+ const e = Math.min(s + batchSize, total);
131
+ const batch = [];
132
+ for (let i = s; i < e; i += 1)
133
+ batch.push(makeDoc(i));
134
+ store.writeBatch(batch);
135
+ }
136
+ store.flush();
137
+ await waitForWrites(store, total);
138
+ }
139
+ function seedSgv2(graph, persons, friends) {
140
+ for (let i = 0; i < persons; i += 1) {
141
+ graph.addPerson({ id: `p-${i}`, name: `Person ${i}` });
142
+ }
143
+ // friend ring (just enough to populate router::incoming_to)
144
+ const ringEdges = Math.min(friends, persons * 4);
145
+ for (let i = 0; i < ringEdges; i += 1) {
146
+ const a = `p-${i % persons}`;
147
+ const b = `p-${(i * 17 + 3) % persons}`;
148
+ if (a !== b)
149
+ graph.addFriend(a, b);
150
+ }
151
+ // hot company tag (1000 members)
152
+ const hotTag = graph.addTag({ name: 'TechCorp', tagType: 'company' });
153
+ for (let i = 0; i < 1000; i += 1)
154
+ graph.tagPerson(`p-${i}`, hotTag.id);
155
+ // 1000 filler company tags so listTags has volume
156
+ for (let i = 0; i < 1000; i += 1)
157
+ graph.addTag({ name: `Co-${i}`, tagType: 'company' });
158
+ // hot attribute (industry=tech) shared by 800 holders
159
+ const hotAttr = graph.findOrCreateAttribute('industry', 'tech');
160
+ for (let i = 0; i < 800; i += 1)
161
+ graph.setPersonAttribute(`p-${i}`, hotAttr.id);
162
+ return { hotTagId: hotTag.id, hotAttrId: hotAttr.id };
163
+ }
164
+ // ---- per-API drivers ------------------------------------------------------
165
+ function syncFor(scenario, n, f) {
166
+ const start = performance.now();
167
+ let last;
168
+ for (let i = 0; i < n; i += 1)
169
+ last = f();
170
+ if (last === undefined)
171
+ throw new Error(`${scenario}: empty result`);
172
+ const elapsedMs = performance.now() - start;
173
+ return { scenario, ops: n, elapsedMs, throughput: n / (elapsedMs / 1000) };
174
+ }
175
+ async function asyncSeq(scenario, n, f) {
176
+ const start = performance.now();
177
+ let last;
178
+ for (let i = 0; i < n; i += 1)
179
+ last = await f();
180
+ if (last === undefined)
181
+ throw new Error(`${scenario}: empty result`);
182
+ const elapsedMs = performance.now() - start;
183
+ return { scenario, ops: n, elapsedMs, throughput: n / (elapsedMs / 1000) };
184
+ }
185
+ async function asyncPar(scenario, n, concurrency, f) {
186
+ const start = performance.now();
187
+ let next = 0;
188
+ let last;
189
+ await Promise.all(Array.from({ length: concurrency }, async () => {
190
+ while (true) {
191
+ const i = next;
192
+ next += 1;
193
+ if (i >= n)
194
+ break;
195
+ last = await f();
196
+ }
197
+ }));
198
+ if (last === undefined)
199
+ throw new Error(`${scenario}: empty result`);
200
+ const elapsedMs = performance.now() - start;
201
+ return { scenario, ops: n, elapsedMs, throughput: n / (elapsedMs / 1000) };
202
+ }
203
+ async function main() {
204
+ const options = parseArgs();
205
+ console.log('============================================================');
206
+ console.log(' phase-380/T380.4 — async wrapper concurrent throughput');
207
+ console.log('============================================================');
208
+ console.log(` cdsDocs=${options.cdsDocs}, sgv2Persons=${options.sgv2Persons}, sgv2Friends=${options.sgv2Friends}, scanOps=${options.scanOps}`);
209
+ console.log(` concurrency=${options.concurrency}, shards=${options.shardCount}, CPU=${os.cpus().length}, Node=${process.version}`);
210
+ console.log('');
211
+ const cdsDir = makeTempDir('phase380-bench-cds-');
212
+ const sgvDir = makeTempDir('phase380-bench-sgv-');
213
+ const cds = new concurrent_document_store_1.ConcurrentDocumentStore(path.join(cdsDir, 'store'), {
214
+ shardCount: options.shardCount,
215
+ enableWal: false,
216
+ mode: 'high_throughput',
217
+ enableFileLock: false,
218
+ });
219
+ const graph = new social_graph_v2_1.SocialGraphV2({ path: path.join(sgvDir, 'graph'), walEnabled: false });
220
+ try {
221
+ console.log(' → seeding CDS...');
222
+ const t0 = performance.now();
223
+ await seedCds(cds, options.cdsDocs);
224
+ console.log(` seeded ${options.cdsDocs} docs in ${(performance.now() - t0).toFixed(0)} ms`);
225
+ console.log(' → seeding SGV2...');
226
+ const t1 = performance.now();
227
+ const sgv = seedSgv2(graph, options.sgv2Persons, options.sgv2Friends);
228
+ console.log(` seeded ${options.sgv2Persons} persons in ${(performance.now() - t1).toFixed(0)} ms`);
229
+ const results = [];
230
+ // ---- CDS findByTag ----
231
+ console.log('');
232
+ console.log(' → CDS.findByTag (limit=10) sync seq...');
233
+ results.push(syncFor('CDS.findByTag.sync.seq', options.scanOps, () => cds.findByTag('bench', { limit: 10 })));
234
+ console.log(' → CDS.findByTag (limit=10) async seq...');
235
+ results.push(await asyncSeq('CDS.findByTag.async.seq', options.scanOps, () => cds.findByTagAsync('bench', { limit: 10 })));
236
+ console.log(` → CDS.findByTag (limit=10) async par=${options.concurrency}...`);
237
+ results.push(await asyncPar('CDS.findByTag.async.par', options.scanOps, options.concurrency, () => cds.findByTagAsync('bench', { limit: 10 })));
238
+ // ---- CDS findByMetadata ----
239
+ console.log(' → CDS.findByMetadata (priority=3, limit=10) sync seq...');
240
+ results.push(syncFor('CDS.findByMetadata.sync.seq', options.scanOps, () => cds.findByMetadata({ priority: 3 }, { limit: 10 })));
241
+ console.log(' → CDS.findByMetadata (priority=3, limit=10) async seq...');
242
+ results.push(await asyncSeq('CDS.findByMetadata.async.seq', options.scanOps, () => cds.findByMetadataAsync({ priority: 3 }, { limit: 10 })));
243
+ console.log(` → CDS.findByMetadata (priority=3, limit=10) async par=${options.concurrency}...`);
244
+ results.push(await asyncPar('CDS.findByMetadata.async.par', options.scanOps, options.concurrency, () => cds.findByMetadataAsync({ priority: 3 }, { limit: 10 })));
245
+ // ---- SGV2 getTagMembers ----
246
+ console.log(' → SGV2.getTagMembers (limit=10) sync seq...');
247
+ results.push(syncFor('SGV2.getTagMembers.sync.seq', options.scanOps, () => graph.getTagMembers(sgv.hotTagId, { limit: 10 })));
248
+ console.log(' → SGV2.getTagMembers (limit=10) async seq...');
249
+ results.push(await asyncSeq('SGV2.getTagMembers.async.seq', options.scanOps, () => graph.getTagMembersAsync(sgv.hotTagId, { limit: 10 })));
250
+ console.log(` → SGV2.getTagMembers (limit=10) async par=${options.concurrency}...`);
251
+ results.push(await asyncPar('SGV2.getTagMembers.async.par', options.scanOps, options.concurrency, () => graph.getTagMembersAsync(sgv.hotTagId, { limit: 10 })));
252
+ // ---- SGV2 listTags ----
253
+ console.log(' → SGV2.listTags (company, limit=10) sync seq...');
254
+ results.push(syncFor('SGV2.listTags.sync.seq', options.scanOps, () => graph.listTags({ tagType: 'company', limit: 10 })));
255
+ console.log(' → SGV2.listTags (company, limit=10) async seq...');
256
+ results.push(await asyncSeq('SGV2.listTags.async.seq', options.scanOps, () => graph.listTagsAsync({ tagType: 'company', limit: 10 })));
257
+ console.log(` → SGV2.listTags (company, limit=10) async par=${options.concurrency}...`);
258
+ results.push(await asyncPar('SGV2.listTags.async.par', options.scanOps, options.concurrency, () => graph.listTagsAsync({ tagType: 'company', limit: 10 })));
259
+ // ---- SGV2 getPersonsByAttribute ----
260
+ console.log(' → SGV2.getPersonsByAttribute (limit=10) sync seq...');
261
+ results.push(syncFor('SGV2.getPersonsByAttribute.sync.seq', options.scanOps, () => graph.getPersonsByAttribute(sgv.hotAttrId, { limit: 10 })));
262
+ console.log(' → SGV2.getPersonsByAttribute (limit=10) async seq...');
263
+ results.push(await asyncSeq('SGV2.getPersonsByAttribute.async.seq', options.scanOps, () => graph.getPersonsByAttributeAsync(sgv.hotAttrId, { limit: 10 })));
264
+ console.log(` → SGV2.getPersonsByAttribute (limit=10) async par=${options.concurrency}...`);
265
+ results.push(await asyncPar('SGV2.getPersonsByAttribute.async.par', options.scanOps, options.concurrency, () => graph.getPersonsByAttributeAsync(sgv.hotAttrId, { limit: 10 })));
266
+ // ---- Summary ----
267
+ console.log('');
268
+ console.log('============================================================');
269
+ console.log(' Throughput summary (ops/s)');
270
+ console.log('============================================================');
271
+ for (const r of results) {
272
+ console.log(` ${r.scenario.padEnd(40)} ${fmt(Math.round(r.throughput))}`);
273
+ }
274
+ console.log('');
275
+ console.log('============================================================');
276
+ console.log(' Decision gate (per-path lift = par / sync.seq)');
277
+ console.log('============================================================');
278
+ const apis = [
279
+ 'CDS.findByTag',
280
+ 'CDS.findByMetadata',
281
+ 'SGV2.getTagMembers',
282
+ 'SGV2.listTags',
283
+ 'SGV2.getPersonsByAttribute',
284
+ ];
285
+ let allKeep = true;
286
+ let allNoRegress = true;
287
+ for (const api of apis) {
288
+ const sync = results.find((r) => r.scenario === `${api}.sync.seq`);
289
+ const aSeq = results.find((r) => r.scenario === `${api}.async.seq`);
290
+ const aPar = results.find((r) => r.scenario === `${api}.async.par`);
291
+ const lift = aPar.throughput / sync.throughput;
292
+ const overhead = sync.throughput / aSeq.throughput;
293
+ const keepPass = lift >= 1.5;
294
+ const noRegress = overhead <= 5.0;
295
+ console.log(` ${api.padEnd(36)} sync=${fmt(Math.round(sync.throughput))} asyncSeq=${fmt(Math.round(aSeq.throughput))} ` +
296
+ `asyncPar=${fmt(Math.round(aPar.throughput))} lift=${lift.toFixed(2)}x spawnOH=${overhead.toFixed(2)}x ` +
297
+ `${keepPass ? 'KEEP' : 'DISCARD'} ${noRegress ? 'NO-REG' : 'REGRESSED'}`);
298
+ if (!keepPass)
299
+ allKeep = false;
300
+ if (!noRegress)
301
+ allNoRegress = false;
302
+ }
303
+ console.log('');
304
+ console.log(` H-A/B (lift >= 1.5x): ${allKeep ? 'PASS' : 'FAIL'}`);
305
+ console.log(` H-C (spawn OH <= 5x): ${allNoRegress ? 'PASS' : 'FAIL'}`);
306
+ console.log('');
307
+ console.log('--- results.tsv-ready summary rows ---');
308
+ for (const r of results) {
309
+ console.log(`phase-380\t${r.scenario}\t${Math.round(r.throughput)}\tops/s`);
310
+ }
311
+ }
312
+ finally {
313
+ await cds.closeAsync().catch(() => undefined);
314
+ cleanupDir(cdsDir);
315
+ cleanupDir(sgvDir);
316
+ }
317
+ }
318
+ main().catch((err) => {
319
+ console.error('phase-380 bench failed:', err);
320
+ process.exit(1);
321
+ });
322
+ //# sourceMappingURL=find-async-bench.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-async-bench.js","sourceRoot":"","sources":["../ts/find-async-bench.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * phase-380/T380.2 (E380.A) — semantic regression guard for the new
4
+ * `findByTagAsync` / `findByMetadataAsync` NAPI async wrappers.
5
+ *
6
+ * Important: the underlying `find_by_tag_limited` /
7
+ * `find_by_metadata_limited` core APIs explicitly document
8
+ * "any matching subset, no order guarantee" — the inverse-index
9
+ * HashSet iter order is implementation-defined, so when total_hits
10
+ * exceeds the requested limit, two calls may pick a different N-element
11
+ * prefix. We therefore verify the *contract* the async wrapper must
12
+ * uphold, not byte-equality:
13
+ *
14
+ * 1. Result length matches sync wrapper for the same arguments.
15
+ * 2. Every returned node passes the predicate (correct filter).
16
+ * 3. When limit >= total_hits, the element set is exactly the sync
17
+ * element set (sorted-id projection equality).
18
+ *
19
+ * Run after `npx tsc`:
20
+ * node packages/node/dist/find-async-verify.js
21
+ */
22
+ export {};
23
+ //# sourceMappingURL=find-async-verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find-async-verify.d.ts","sourceRoot":"","sources":["../ts/find-async-verify.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;GAmBG"}
@@ -0,0 +1,286 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * phase-380/T380.2 (E380.A) — semantic regression guard for the new
5
+ * `findByTagAsync` / `findByMetadataAsync` NAPI async wrappers.
6
+ *
7
+ * Important: the underlying `find_by_tag_limited` /
8
+ * `find_by_metadata_limited` core APIs explicitly document
9
+ * "any matching subset, no order guarantee" — the inverse-index
10
+ * HashSet iter order is implementation-defined, so when total_hits
11
+ * exceeds the requested limit, two calls may pick a different N-element
12
+ * prefix. We therefore verify the *contract* the async wrapper must
13
+ * uphold, not byte-equality:
14
+ *
15
+ * 1. Result length matches sync wrapper for the same arguments.
16
+ * 2. Every returned node passes the predicate (correct filter).
17
+ * 3. When limit >= total_hits, the element set is exactly the sync
18
+ * element set (sorted-id projection equality).
19
+ *
20
+ * Run after `npx tsc`:
21
+ * node packages/node/dist/find-async-verify.js
22
+ */
23
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
24
+ if (k2 === undefined) k2 = k;
25
+ var desc = Object.getOwnPropertyDescriptor(m, k);
26
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
27
+ desc = { enumerable: true, get: function() { return m[k]; } };
28
+ }
29
+ Object.defineProperty(o, k2, desc);
30
+ }) : (function(o, m, k, k2) {
31
+ if (k2 === undefined) k2 = k;
32
+ o[k2] = m[k];
33
+ }));
34
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
35
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
36
+ }) : function(o, v) {
37
+ o["default"] = v;
38
+ });
39
+ var __importStar = (this && this.__importStar) || (function () {
40
+ var ownKeys = function(o) {
41
+ ownKeys = Object.getOwnPropertyNames || function (o) {
42
+ var ar = [];
43
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
44
+ return ar;
45
+ };
46
+ return ownKeys(o);
47
+ };
48
+ return function (mod) {
49
+ if (mod && mod.__esModule) return mod;
50
+ var result = {};
51
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
52
+ __setModuleDefault(result, mod);
53
+ return result;
54
+ };
55
+ })();
56
+ Object.defineProperty(exports, "__esModule", { value: true });
57
+ const fs = __importStar(require("fs"));
58
+ const os = __importStar(require("os"));
59
+ const path = __importStar(require("path"));
60
+ const concurrent_document_store_1 = require("./concurrent-document-store");
61
+ const TAG_POOL = ['bench', 'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 'eta'];
62
+ function makeDoc(index) {
63
+ return {
64
+ id: `doc-${index}`,
65
+ content: `phase-380 verify payload #${index}`,
66
+ tags: [TAG_POOL[index % TAG_POOL.length], TAG_POOL[(index * 3 + 1) % TAG_POOL.length]],
67
+ docType: index % 2 === 0 ? 'note' : 'report',
68
+ importance: (index % 100) / 100,
69
+ metadata: {
70
+ source: `bench-${index % 16}`,
71
+ bucket: index % 64,
72
+ priority: 1 + (index % 5),
73
+ active: index % 2 === 0,
74
+ },
75
+ };
76
+ }
77
+ function makeTempDir(prefix) {
78
+ return fs.mkdtempSync(path.join(os.tmpdir(), prefix));
79
+ }
80
+ function cleanupDir(dir) {
81
+ try {
82
+ fs.rmSync(dir, { recursive: true, force: true });
83
+ }
84
+ catch {
85
+ /* swallow */
86
+ }
87
+ }
88
+ function idsSorted(nodes) {
89
+ return nodes.map((n) => n.id).sort();
90
+ }
91
+ function sleep(ms) {
92
+ return new Promise((resolve) => setTimeout(resolve, ms));
93
+ }
94
+ async function waitForWrites(store, expected, timeoutMs = 30000) {
95
+ const deadline = performance.now() + timeoutMs;
96
+ while (performance.now() < deadline) {
97
+ if (store.metrics().successfulWrites >= expected)
98
+ return;
99
+ await sleep(1);
100
+ }
101
+ }
102
+ async function seedStore(store, options) {
103
+ const batchSize = 2000;
104
+ for (let start = 0; start < options.docs; start += batchSize) {
105
+ const end = Math.min(start + batchSize, options.docs);
106
+ const batch = [];
107
+ for (let i = start; i < end; i += 1)
108
+ batch.push(makeDoc(i));
109
+ store.writeBatch(batch);
110
+ }
111
+ store.flush();
112
+ await waitForWrites(store, options.docs);
113
+ }
114
+ function checkPredicate(nodes, predicate) {
115
+ for (const n of nodes) {
116
+ if (!predicate(n))
117
+ return { ok: false, firstFailingId: n.id };
118
+ }
119
+ return { ok: true };
120
+ }
121
+ async function checkFindByTag(store, tag, limit, totalHitsForTag) {
122
+ const sync = store.findByTag(tag, { limit });
123
+ const a = await store.findByTagAsync(tag, { limit });
124
+ if (sync.length !== a.length) {
125
+ return {
126
+ scenario: `findByTag(tag=${tag}, limit=${limit})`,
127
+ count: sync.length,
128
+ pass: false,
129
+ detail: `length mismatch: sync=${sync.length} async=${a.length}`,
130
+ };
131
+ }
132
+ const pred = (n) => (n.tags ?? []).includes(tag);
133
+ const sp = checkPredicate(sync, pred);
134
+ const ap = checkPredicate(a, pred);
135
+ if (!sp.ok) {
136
+ return {
137
+ scenario: `findByTag(tag=${tag}, limit=${limit})`,
138
+ count: sync.length,
139
+ pass: false,
140
+ detail: `sync returned non-matching id ${sp.firstFailingId}`,
141
+ };
142
+ }
143
+ if (!ap.ok) {
144
+ return {
145
+ scenario: `findByTag(tag=${tag}, limit=${limit})`,
146
+ count: sync.length,
147
+ pass: false,
148
+ detail: `async returned non-matching id ${ap.firstFailingId}`,
149
+ };
150
+ }
151
+ // When the requested limit covers the whole population, the element set
152
+ // must be byte-identical (sorted by id).
153
+ if (limit >= totalHitsForTag) {
154
+ const ks = JSON.stringify(idsSorted(sync));
155
+ const ka = JSON.stringify(idsSorted(a));
156
+ if (ks !== ka) {
157
+ return {
158
+ scenario: `findByTag(tag=${tag}, limit=${limit})`,
159
+ count: sync.length,
160
+ pass: false,
161
+ detail: `full-set element mismatch (limit ${limit} >= ${totalHitsForTag})`,
162
+ };
163
+ }
164
+ }
165
+ return {
166
+ scenario: `findByTag(tag=${tag}, limit=${limit})`,
167
+ count: sync.length,
168
+ pass: true,
169
+ };
170
+ }
171
+ function metaMatches(n, filters) {
172
+ for (const [k, v] of Object.entries(filters)) {
173
+ const m = n.metadata;
174
+ if (!m)
175
+ return false;
176
+ if (typeof v === 'object' && v !== null) {
177
+ const ops = v;
178
+ const cell = m[k];
179
+ if (typeof cell !== 'number')
180
+ return false;
181
+ if ('$gte' in ops && !(cell >= ops['$gte']))
182
+ return false;
183
+ if ('$gt' in ops && !(cell > ops['$gt']))
184
+ return false;
185
+ if ('$lte' in ops && !(cell <= ops['$lte']))
186
+ return false;
187
+ if ('$lt' in ops && !(cell < ops['$lt']))
188
+ return false;
189
+ }
190
+ else {
191
+ if (m[k] !== v)
192
+ return false;
193
+ }
194
+ }
195
+ return true;
196
+ }
197
+ async function checkFindByMetadata(store, filters, limit, totalHits) {
198
+ const sync = store.findByMetadata(filters, { limit });
199
+ const a = await store.findByMetadataAsync(filters, { limit });
200
+ const tag = `findByMetadata(${JSON.stringify(filters)}, limit=${limit})`;
201
+ if (sync.length !== a.length) {
202
+ return { scenario: tag, count: sync.length, pass: false, detail: `length mismatch: sync=${sync.length} async=${a.length}` };
203
+ }
204
+ const pred = (n) => metaMatches(n, filters);
205
+ const sp = checkPredicate(sync, pred);
206
+ const ap = checkPredicate(a, pred);
207
+ if (!sp.ok)
208
+ return { scenario: tag, count: sync.length, pass: false, detail: `sync non-matching ${sp.firstFailingId}` };
209
+ if (!ap.ok)
210
+ return { scenario: tag, count: sync.length, pass: false, detail: `async non-matching ${ap.firstFailingId}` };
211
+ if (limit >= totalHits) {
212
+ const ks = JSON.stringify(idsSorted(sync));
213
+ const ka = JSON.stringify(idsSorted(a));
214
+ if (ks !== ka) {
215
+ return { scenario: tag, count: sync.length, pass: false, detail: `full-set element mismatch (limit ${limit} >= ${totalHits})` };
216
+ }
217
+ }
218
+ return { scenario: tag, count: sync.length, pass: true };
219
+ }
220
+ async function main() {
221
+ const dir = makeTempDir('phase380-verify-');
222
+ const store = new concurrent_document_store_1.ConcurrentDocumentStore(path.join(dir, 'store'), {
223
+ shardCount: 16,
224
+ enableWal: false,
225
+ mode: 'high_throughput',
226
+ enableFileLock: false,
227
+ });
228
+ console.log('============================================================');
229
+ console.log(' phase-380/T380.2 — find{ByTag,ByMetadata}Async semantic verify');
230
+ console.log('============================================================');
231
+ try {
232
+ const docs = 5000;
233
+ console.log(` → seeding ${docs} docs...`);
234
+ await seedStore(store, { docs, shardCount: 16 });
235
+ // Compute oracle counts for full-set assertions.
236
+ const totalBench = store.countByTag('bench');
237
+ const totalZeta = store.countByTag('zeta');
238
+ const totalAlpha = store.countByTag('alpha');
239
+ const totalPrio3 = store.countByMetadata({ priority: 3 });
240
+ const totalPrio2Active = store.countByMetadata({ priority: 2, active: true });
241
+ const totalPrioGte3Op = store.findByMetadata({ priority: { $gte: 3 } }).length;
242
+ console.log(` counts: bench=${totalBench} zeta=${totalZeta} alpha=${totalAlpha} ` +
243
+ `prio=3 ${totalPrio3} prio=2&active ${totalPrio2Active} prio>=3 ${totalPrioGte3Op}`);
244
+ const checks = [];
245
+ checks.push(await checkFindByTag(store, 'bench', 10, totalBench));
246
+ checks.push(await checkFindByTag(store, 'bench', 50, totalBench));
247
+ checks.push(await checkFindByTag(store, 'alpha', 10, totalAlpha));
248
+ checks.push(await checkFindByTag(store, 'zeta', 100, totalZeta));
249
+ checks.push(await checkFindByTag(store, 'zeta', totalZeta + 50, totalZeta)); // covers full set
250
+ checks.push(await checkFindByMetadata(store, { priority: 3 }, 10, totalPrio3));
251
+ checks.push(await checkFindByMetadata(store, { priority: 3 }, 50, totalPrio3));
252
+ checks.push(await checkFindByMetadata(store, { priority: 3 }, totalPrio3 + 10, totalPrio3)); // covers full set
253
+ checks.push(await checkFindByMetadata(store, { priority: 2, active: true }, 10, totalPrio2Active));
254
+ checks.push(await checkFindByMetadata(store, { priority: 2, active: true }, totalPrio2Active + 10, totalPrio2Active)); // covers full set
255
+ checks.push(await checkFindByMetadata(store, { priority: { $gte: 3 } }, 10, totalPrioGte3Op));
256
+ console.log('');
257
+ let allPass = true;
258
+ for (const c of checks) {
259
+ const tag = c.pass ? 'PASS' : 'FAIL';
260
+ console.log(` ${tag} ${c.scenario.padEnd(60)} count=${c.count}`);
261
+ if (!c.pass) {
262
+ console.log(` \u21B3 ${c.detail}`);
263
+ allPass = false;
264
+ }
265
+ }
266
+ console.log('');
267
+ if (allPass) {
268
+ console.log(' \u2713 all scenarios pass');
269
+ console.log(' contract: length-match + per-node predicate + full-set equality when limit >= total');
270
+ process.exit(0);
271
+ }
272
+ else {
273
+ console.log(' \u2717 regressions detected');
274
+ process.exit(1);
275
+ }
276
+ }
277
+ finally {
278
+ await store.closeAsync().catch(() => undefined);
279
+ cleanupDir(dir);
280
+ }
281
+ }
282
+ main().catch((err) => {
283
+ console.error('phase-380 verify failed:', err);
284
+ process.exit(1);
285
+ });
286
+ //# sourceMappingURL=find-async-verify.js.map