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.
46 lines
2.2 KiB
JavaScript
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); });
|