Files
MultiforaDB/tests/e2e/concurrent.js
Aleksey Shakhmatov d4c9b04f21 rename project to MultiforaDB
Prose and benchmark tables use MultiforaDB; the binary, the CLI usage
line, the log-message prefix and the default database file use
multiforadb.

Two consequences worth noting:

- build.zig.zon's fingerprint is derived from the package name, so it
  had to change with it (Zig refuses to build otherwise). A consumer
  pinning this package by fingerprint needs updating.
- the default --db path is now multiforadb.log, and getCmdLineOpts
  reports it as dbpath. An existing mongo-lite.log has to be passed
  explicitly with --db.

The e2e harness abbreviated the old name as ML_; that is now MFDB_,
including the documented ML_BIN override (MFDB_BIN) and the scratch
file names. MD_ (mongod) is untouched.

compare-run.sh spawned the server by absolute path under a
sandbox/mongo-lite directory that no longer exists; that block already
runs from tests/e2e, so it uses a relative path now.

The archived reports under tests/e2e/results/ keep the old name: they
record what the old binary measured.
2026-08-03 12:35:01 +03:00

46 lines
2.2 KiB
JavaScript

// Concurrent durable-write benchmark: N clients each do M sequential
// insertOne ({w:1, j:true} by default) into their own collection, reporting
// aggregate docs/s. Exercises the group-commit path under real contention.
//
// node tests/e2e/concurrent.js --url mongodb://127.0.0.1:27019 --label multiforadb
// [--clients 8] [--per-client 2000] [--wc j|none]
//
// Output (stdout, tab-separated, one line):
// <label> clients=N <docs/s> (M docs in S s)
const { MongoClient, ObjectId } = require('mongodb');
let opt = { url: null, label: null, clients: 8, perClient: 2000, wc: 'j' };
for (let i = 2; i < process.argv.length; i++) {
const a = process.argv[i];
if (a === '--url') opt.url = process.argv[++i];
else if (a === '--label') opt.label = process.argv[++i];
else if (a === '--clients') opt.clients = Number(process.argv[++i]);
else if (a === '--per-client') opt.perClient = Number(process.argv[++i]);
else if (a === '--wc') opt.wc = process.argv[++i];
else { console.error(`unknown option ${a}`); process.exit(2); }
}
if (!opt.url) { console.error('--url required'); process.exit(2); }
opt.label = opt.label || opt.url.replace(/^mongodb:\/\//, '');
const WC = opt.wc === 'j' ? { writeConcern: { w: 1, j: true } } : {};
async function worker(i) {
const c = new MongoClient(opt.url, { maxPoolSize: 4, serverSelectionTimeoutMS: 15000 });
await c.connect();
// One collection per worker in a scratch db, so no cross-worker contention
// beyond the engine's own commit path.
const coll = c.db(`cc${Date.now() % 100000}`).collection(`w${i}`);
for (let j = 0; j < opt.perClient; j++) {
await coll.insertOne({ _id: new ObjectId(), k: j, payload: 'x'.repeat(256) }, WC);
}
await c.close();
}
(async () => {
const t0 = process.hrtime.bigint();
await Promise.all(Array.from({ length: opt.clients }, (_, i) => worker(i)));
const s = Number(process.hrtime.bigint() - t0) / 1e9;
const total = opt.clients * opt.perClient;
console.log(`${opt.label}\tclients=${opt.clients}\t${(total / s).toFixed(0)} docs/s\t(${total} docs in ${s.toFixed(2)} s)`);
process.exit(0);
})().catch((e) => { console.error('FAIL', e); process.exit(1); });