@peerbit/document 13.0.44 → 13.1.0

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.
@@ -32,25 +32,99 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
32
32
  }
33
33
  return useValue ? value : void 0;
34
34
  };
35
- import { field, option, variant } from "@dao-xyz/borsh";
35
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
36
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
37
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
38
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
39
+ });
40
+ }
41
+ return path;
42
+ };
43
+ import { field, option, serialize, variant } from "@dao-xyz/borsh";
44
+ import { create as createSimpleIndexer } from "@peerbit/indexer-simple";
45
+ import { create as createSqliteIndexer } from "@peerbit/indexer-sqlite3";
46
+ import { Log } from "@peerbit/log";
47
+ import { NativeBackboneNodeCoordinatePersistence, NativeBackboneNodeCoordinatePersistenceStore, createBufferedNativeBackboneCoordinatePersistence, createBufferedNativeBackboneNodeCoordinatePersistence, createNativePeerbitBackbone, defaultNativeBackboneCoordinateFlushMaxPendingBytes, } from "@peerbit/native-backbone";
36
48
  import { Program } from "@peerbit/program";
37
49
  import { TestSession } from "@peerbit/test-utils";
38
- import { Bench } from "tinybench";
39
- import { Documents } from "../src/program.js";
50
+ import { createRustPeerbitOptions } from "peerbit/rust";
51
+ import { Documents, policy, transform, } from "../src/index.js";
40
52
  // Run with:
41
53
  // cd packages/programs/data/document/document
42
54
  // node --loader ts-node/esm ./benchmark/document-put.ts
43
55
  //
44
56
  // Env:
45
- // - DOC_WARMUP=1000
46
- // - DOC_ITERATIONS=200
57
+ // - DOC_WARMUP=100
58
+ // - DOC_ITERATIONS=1000
47
59
  // - DOC_BYTES=1200
48
- // - BENCH_JSON=1 (emit machine-readable JSON)
60
+ // - DOC_COORDINATE_WAL_FLUSH_BYTES=1048576
61
+ // - DOC_COORDINATE_WAL_FLUSH_INTERVAL_MS unset by default
62
+ // - DOC_SCENARIOS=compat-path,hybrid-anystore,simple-index,sqlite-index,native-graph,native-block-store,rust-peerbit,rust-peerbit-local,rust-peerbit-transient-index,rust-peerbit-backbone-local,rust-peerbit-backbone-local-document-index,rust-peerbit-backbone-coordinate-wal,rust-peerbit-backbone-coordinate-wal-buffered,native-ceiling,native-log-core-ceiling,native-log-digest-key-core-ceiling,native-log-crypto-ceiling,native-log-ceiling,native-backbone-ceiling,native-backbone-storage-ceiling,native-backbone-loop-ceiling
63
+ // Add "-nonunique" to any scenario name to use default update-safe put semantics with new ids.
64
+ // Add "-update" to any scenario name to repeatedly update one document id.
65
+ // Add "-local" to a rust-peerbit scenario to disable replication and default trim.
66
+ // Add "-trim" to a local rust-peerbit scenario to keep length trim enabled.
67
+ // Add "-no-trim" to any rust-peerbit scenario to disable length trim.
68
+ // Add "-trim-from-200" to any trimmed rust-peerbit scenario to trim to 100 only after length reaches 200.
69
+ // Add "-putmany" to any scenario name to use one putMany call per measured batch.
70
+ // Add "-document-index" to a rust-peerbit-backbone scenario to enable nativeBackbone.documentIndex.
71
+ // Add "-direct" to a coordinate-WAL rust-peerbit-backbone scenario to use the direct Node coordinate persistence adapter.
72
+ // Add "-mode-native" to a rust-peerbit-backbone scenario to open Documents in strict native mode.
73
+ // Strict native scenarios use buffered coordinate WAL even without an explicit "-coordinate-wal" suffix.
74
+ // Add "-mode-native-replicated" to keep open-level replication in strict native mode.
75
+ // Add "-policy-allow-all" to open with canPerform: policy.allowAll().
76
+ // Add "-policy-signed-public-key" to open with canPerform: policy.signedByPublicKey(local public key).
77
+ // Add "-policy-put-signed-public-key" to open with canPerform: policy.put(policy.signedByPublicKey(local public key)).
78
+ // Add "-policy-put-signed-field" to open with canPerform: policy.put(policy.signedByField("signer")).
79
+ // Add "-policy-put-same-signer" to open with canPerform: policy.put(policy.sameSignersAsPrevious()).
80
+ // Add "-canperform-allow-all" to open with canPerform: () => true.
81
+ // Add "-transform-identity", "-transform-pick", "-transform-project-context", or "-transform-arbitrary" to compare index transform paths.
82
+ // - DOC_PROFILE_DEEP=1 reports lower shared-log/log phase timings.
83
+ // - BENCH_JSON=1
49
84
  const payloadBytes = Math.max(1, Number.parseInt(process.env.DOC_BYTES || "1200", 10) || 1200);
50
- const warmupIterations = Number.parseInt(process.env.DOC_WARMUP || "1000", 10);
51
- const iterations = process.env.DOC_ITERATIONS
52
- ? Number.parseInt(process.env.DOC_ITERATIONS, 10)
53
- : undefined;
85
+ const warmupIterations = Math.max(0, Number.parseInt(process.env.DOC_WARMUP || "100", 10) || 0);
86
+ const iterations = Math.max(1, Number.parseInt(process.env.DOC_ITERATIONS || "1000", 10) || 1000);
87
+ const coordinateWalFlushBytes = Math.max(0, Number.parseInt(process.env.DOC_COORDINATE_WAL_FLUSH_BYTES ||
88
+ String(defaultNativeBackboneCoordinateFlushMaxPendingBytes), 10) || defaultNativeBackboneCoordinateFlushMaxPendingBytes);
89
+ const coordinateWalFlushIntervalMs = process.env.DOC_COORDINATE_WAL_FLUSH_INTERVAL_MS == null
90
+ ? undefined
91
+ : Math.max(0, Number.parseInt(process.env.DOC_COORDINATE_WAL_FLUSH_INTERVAL_MS, 10) ||
92
+ 0);
93
+ const scenarioNames = (process.env.DOC_SCENARIOS ||
94
+ "compat-path,hybrid-anystore,simple-index,sqlite-index,native-graph,native-block-store,rust-peerbit,rust-peerbit-transient-index")
95
+ .split(",")
96
+ .map((x) => x.trim())
97
+ .filter(Boolean);
98
+ const scenarioBaseName = (name) => name.replace(/(?:-(?:putmany|nonunique|update|local|no-trim|trim-from-200|trim|buffered|direct|coordinate-wal|document-index|mode-native-replicated|mode-native|policy-allow-all|policy-signed-public-key|policy-put-signed-public-key|policy-put-signed-field|policy-put-same-signer|canperform-allow-all|transform-identity|transform-pick|transform-project-context|transform-arbitrary))*$/, "");
99
+ const scenarioUsesUpdatePuts = (name) => name.includes("-update");
100
+ const scenarioUsesUniquePuts = (name) => !name.includes("-nonunique") && !scenarioUsesUpdatePuts(name);
101
+ const scenarioUsesPutMany = (name) => name.endsWith("-putmany");
102
+ const scenarioUsesLocalStore = (name) => scenarioBaseName(name).startsWith("rust-peerbit") && name.includes("-local");
103
+ const scenarioDisablesTrim = (name) => name.includes("-no-trim");
104
+ const scenarioUsesTrim = (name) => name.includes("-trim") && !scenarioDisablesTrim(name);
105
+ const scenarioUsesTrimHysteresis = (name) => name.includes("-trim-from-200");
106
+ const scenarioTrimOptions = (name) => scenarioUsesTrimHysteresis(name)
107
+ ? { type: "length", to: 100, from: 200 }
108
+ : { type: "length", to: 100 };
109
+ const scenarioUsesCoordinateWal = (name) => name.includes("-coordinate-wal");
110
+ const scenarioUsesBufferedCoordinateWal = (name) => name.includes("-coordinate-wal-buffered");
111
+ const scenarioUsesDirectCoordinateWal = (name) => scenarioUsesCoordinateWal(name) && name.includes("-direct");
112
+ const scenarioUsesNativeBackboneDocumentIndex = (name) => name.includes("-document-index");
113
+ const scenarioUsesNativeMode = (name) => name.includes("-mode-native");
114
+ const scenarioUsesNativeModeReplicated = (name) => name.includes("-mode-native-replicated");
115
+ const scenarioUsesPolicyAllowAll = (name) => name.includes("-policy-allow-all");
116
+ const scenarioUsesPolicySignedPublicKey = (name) => name.includes("-policy-signed-public-key");
117
+ const scenarioUsesPolicyPutSignedPublicKey = (name) => name.includes("-policy-put-signed-public-key");
118
+ const scenarioUsesPolicyPutSignedField = (name) => name.includes("-policy-put-signed-field");
119
+ const scenarioUsesPolicyPutSameSigner = (name) => name.includes("-policy-put-same-signer");
120
+ const scenarioUsesCanPerformAllowAll = (name) => name.includes("-canperform-allow-all");
121
+ const scenarioUsesTransformIdentity = (name) => name.includes("-transform-identity");
122
+ const scenarioUsesTransformPick = (name) => name.includes("-transform-pick");
123
+ const scenarioUsesTransformProjectContext = (name) => name.includes("-transform-project-context");
124
+ const scenarioUsesTransformArbitrary = (name) => name.includes("-transform-arbitrary");
125
+ const profileDeep = process.env.DOC_PROFILE_DEEP === "1";
126
+ const profileNativeBackbone = process.env.DOC_NATIVE_PROFILE === "1";
127
+ let currentSignerFieldBytes;
54
128
  let Document = (() => {
55
129
  let _classDecorators = [variant("document")];
56
130
  let _classDescriptor;
@@ -68,6 +142,9 @@ let Document = (() => {
68
142
  let _bytes_decorators;
69
143
  let _bytes_initializers = [];
70
144
  let _bytes_extraInitializers = [];
145
+ let _signer_decorators;
146
+ let _signer_initializers = [];
147
+ let _signer_extraInitializers = [];
71
148
  var Document = class {
72
149
  static { _classThis = this; }
73
150
  static {
@@ -76,10 +153,12 @@ let Document = (() => {
76
153
  _name_decorators = [field({ type: option("string") })];
77
154
  _number_decorators = [field({ type: option("u64") })];
78
155
  _bytes_decorators = [field({ type: Uint8Array })];
156
+ _signer_decorators = [field({ type: option(Uint8Array) })];
79
157
  __esDecorate(null, null, _id_decorators, { kind: "field", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
80
158
  __esDecorate(null, null, _name_decorators, { kind: "field", name: "name", static: false, private: false, access: { has: obj => "name" in obj, get: obj => obj.name, set: (obj, value) => { obj.name = value; } }, metadata: _metadata }, _name_initializers, _name_extraInitializers);
81
159
  __esDecorate(null, null, _number_decorators, { kind: "field", name: "number", static: false, private: false, access: { has: obj => "number" in obj, get: obj => obj.number, set: (obj, value) => { obj.number = value; } }, metadata: _metadata }, _number_initializers, _number_extraInitializers);
82
160
  __esDecorate(null, null, _bytes_decorators, { kind: "field", name: "bytes", static: false, private: false, access: { has: obj => "bytes" in obj, get: obj => obj.bytes, set: (obj, value) => { obj.bytes = value; } }, metadata: _metadata }, _bytes_initializers, _bytes_extraInitializers);
161
+ __esDecorate(null, null, _signer_decorators, { kind: "field", name: "signer", static: false, private: false, access: { has: obj => "signer" in obj, get: obj => obj.signer, set: (obj, value) => { obj.signer = value; } }, metadata: _metadata }, _signer_initializers, _signer_extraInitializers);
83
162
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
84
163
  Document = _classThis = _classDescriptor.value;
85
164
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
@@ -89,13 +168,15 @@ let Document = (() => {
89
168
  name = (__runInitializers(this, _id_extraInitializers), __runInitializers(this, _name_initializers, void 0));
90
169
  number = (__runInitializers(this, _name_extraInitializers), __runInitializers(this, _number_initializers, void 0));
91
170
  bytes = (__runInitializers(this, _number_extraInitializers), __runInitializers(this, _bytes_initializers, void 0));
171
+ signer = (__runInitializers(this, _bytes_extraInitializers), __runInitializers(this, _signer_initializers, void 0));
92
172
  constructor(opts) {
93
- __runInitializers(this, _bytes_extraInitializers);
173
+ __runInitializers(this, _signer_extraInitializers);
94
174
  if (opts) {
95
175
  this.id = opts.id;
96
176
  this.name = opts.name;
97
177
  this.number = opts.number;
98
178
  this.bytes = opts.bytes;
179
+ this.signer = opts.signer;
99
180
  }
100
181
  }
101
182
  };
@@ -133,69 +214,1149 @@ let TestStore = (() => {
133
214
  };
134
215
  return TestStore = _classThis;
135
216
  })();
136
- const peersCount = 1;
137
- const session = await TestSession.connected(peersCount);
138
- const store = new TestStore({
139
- docs: new Documents(),
140
- });
141
- const client = session.peers[0];
142
- await client.open(store, {
143
- args: {
144
- replicate: {
145
- factor: 1,
146
- },
147
- log: {
148
- trim: { type: "length", to: 100 },
149
- },
150
- },
217
+ let PickIndexable = (() => {
218
+ let _classDecorators = [variant("document_put_bench_pick_indexable")];
219
+ let _classDescriptor;
220
+ let _classExtraInitializers = [];
221
+ let _classThis;
222
+ let _id_decorators;
223
+ let _id_initializers = [];
224
+ let _id_extraInitializers = [];
225
+ let _name_decorators;
226
+ let _name_initializers = [];
227
+ let _name_extraInitializers = [];
228
+ var PickIndexable = class {
229
+ static { _classThis = this; }
230
+ static {
231
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
232
+ _id_decorators = [field({ type: "string" })];
233
+ _name_decorators = [field({ type: option("string") })];
234
+ __esDecorate(null, null, _id_decorators, { kind: "field", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
235
+ __esDecorate(null, null, _name_decorators, { kind: "field", name: "name", static: false, private: false, access: { has: obj => "name" in obj, get: obj => obj.name, set: (obj, value) => { obj.name = value; } }, metadata: _metadata }, _name_initializers, _name_extraInitializers);
236
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
237
+ PickIndexable = _classThis = _classDescriptor.value;
238
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
239
+ __runInitializers(_classThis, _classExtraInitializers);
240
+ }
241
+ id = __runInitializers(this, _id_initializers, void 0);
242
+ name = (__runInitializers(this, _id_extraInitializers), __runInitializers(this, _name_initializers, void 0));
243
+ constructor(properties) {
244
+ __runInitializers(this, _name_extraInitializers);
245
+ this.id = properties?.id || "";
246
+ this.name = properties?.name;
247
+ }
248
+ };
249
+ return PickIndexable = _classThis;
250
+ })();
251
+ let ProjectIndexable = (() => {
252
+ let _classDecorators = [variant("document_put_bench_project_indexable")];
253
+ let _classDescriptor;
254
+ let _classExtraInitializers = [];
255
+ let _classThis;
256
+ let _id_decorators;
257
+ let _id_initializers = [];
258
+ let _id_extraInitializers = [];
259
+ let _created_decorators;
260
+ let _created_initializers = [];
261
+ let _created_extraInitializers = [];
262
+ let _signer_decorators;
263
+ let _signer_initializers = [];
264
+ let _signer_extraInitializers = [];
265
+ var ProjectIndexable = class {
266
+ static { _classThis = this; }
267
+ static {
268
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
269
+ _id_decorators = [field({ type: "string" })];
270
+ _created_decorators = [field({ type: "u64" })];
271
+ _signer_decorators = [field({ type: option(Uint8Array) })];
272
+ __esDecorate(null, null, _id_decorators, { kind: "field", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
273
+ __esDecorate(null, null, _created_decorators, { kind: "field", name: "created", static: false, private: false, access: { has: obj => "created" in obj, get: obj => obj.created, set: (obj, value) => { obj.created = value; } }, metadata: _metadata }, _created_initializers, _created_extraInitializers);
274
+ __esDecorate(null, null, _signer_decorators, { kind: "field", name: "signer", static: false, private: false, access: { has: obj => "signer" in obj, get: obj => obj.signer, set: (obj, value) => { obj.signer = value; } }, metadata: _metadata }, _signer_initializers, _signer_extraInitializers);
275
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
276
+ ProjectIndexable = _classThis = _classDescriptor.value;
277
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
278
+ __runInitializers(_classThis, _classExtraInitializers);
279
+ }
280
+ id = __runInitializers(this, _id_initializers, void 0);
281
+ created = (__runInitializers(this, _id_extraInitializers), __runInitializers(this, _created_initializers, void 0));
282
+ signer = (__runInitializers(this, _created_extraInitializers), __runInitializers(this, _signer_initializers, void 0));
283
+ constructor(properties) {
284
+ __runInitializers(this, _signer_extraInitializers);
285
+ this.id = properties?.id || "";
286
+ this.created = properties?.created || 0n;
287
+ this.signer = properties?.signer;
288
+ }
289
+ };
290
+ return ProjectIndexable = _classThis;
291
+ })();
292
+ const importPrivateBenchmarkModule = async (distPath, sourcePath) => {
293
+ try {
294
+ return (await import(__rewriteRelativeImportExtension(new URL(distPath, import.meta.url).href)));
295
+ }
296
+ catch (distError) {
297
+ try {
298
+ return (await import(__rewriteRelativeImportExtension(new URL(sourcePath, import.meta.url).href)));
299
+ }
300
+ catch {
301
+ throw distError;
302
+ }
303
+ }
304
+ };
305
+ let nativeLogBenchmarkHelpersPromise;
306
+ const loadNativeLogBenchmarkHelpers = () => (nativeLogBenchmarkHelpersPromise ??= importPrivateBenchmarkModule("../../../../../log/rust/dist/src/benchmark.js", "../../../../../log/rust/src/benchmark.js"));
307
+ let nativeBackboneBenchmarkHelpersPromise;
308
+ const loadNativeBackboneBenchmarkHelpers = () => (nativeBackboneBenchmarkHelpersPromise ??= importPrivateBenchmarkModule("../../../../../utils/native-backbone/dist/src/benchmark.js", "../../../../../utils/native-backbone/src/benchmark.js"));
309
+ const deepProfileKeys = new Set([
310
+ "documentCommitPlainPutPlanMs",
311
+ "documentCommitNativeAppendMs",
312
+ "documentCreateAppendCommitFactsMs",
313
+ "documentHandlePreparedCommitMs",
314
+ "sharedProcessLocalAppendMs",
315
+ "sharedProcessLocalAppendBatchMs",
316
+ "sharedPlanEntryLeadersMs",
317
+ "sharedLeaderContextMs",
318
+ "sharedCoordinatePrepareMs",
319
+ "sharedPersistCoordinateMs",
320
+ "sharedApplyPreparedFactsMs",
321
+ "sharedCreateAppendCommitMs",
322
+ "sharedMaterializeEntryMs",
323
+ "sharedCoordinateIndexPutMs",
324
+ "sharedNativeBackboneStorageTransactionMs",
325
+ "nativeBackbonePrepareStorageAppendMs",
326
+ "nativeBackbonePrepareNoNextStorageAppendMs",
327
+ "nativeBackbonePrepareStorageAppendWithNextMs",
328
+ "nativeBackbonePrepareCommittedNoNextStorageAppendMs",
329
+ "nativeBackbonePrepareCommittedStorageAppendMs",
330
+ "nativeBackboneStorageAppendInnerMs",
331
+ "nativeBackboneInputCopyMs",
332
+ "nativeBackboneLogTotalMs",
333
+ "nativeBackboneLogNextCloneMs",
334
+ "nativeBackboneLogEntryCoreMs",
335
+ "nativeBackboneLogEncodeMetaMs",
336
+ "nativeBackboneLogEncodePayloadMs",
337
+ "nativeBackboneLogEncodeSignableMs",
338
+ "nativeBackboneLogSignMs",
339
+ "nativeBackboneLogEncodeSignatureMs",
340
+ "nativeBackboneLogEncodeStorageMs",
341
+ "nativeBackboneLogCidMs",
342
+ "nativeBackboneLogCidHashMs",
343
+ "nativeBackboneLogCidStringMs",
344
+ "nativeBackboneLogIndexEntryMs",
345
+ "nativeBackboneLogFactsMs",
346
+ "nativeBackboneLogBlockPutMs",
347
+ "nativeBackboneLogGraphPutMs",
348
+ "nativeBackboneLogTrimMs",
349
+ "nativeBackboneEntryRowMs",
350
+ "nativeBackboneTrimRowsMs",
351
+ "nativeBackboneHashNumberMs",
352
+ "nativeBackboneCoordinatePlanMs",
353
+ "nativeBackboneCoordinateCoreMs",
354
+ "nativeBackboneCoordinateFieldsBuildMs",
355
+ "nativeBackboneCoordinateValueEncodeMs",
356
+ "nativeBackboneCoordinateJournalPutMs",
357
+ "nativeBackboneCoordinateIndexPutMs",
358
+ "nativeBackboneCoordinateValuePutMs",
359
+ "nativeBackboneCoordinateDeleteMs",
360
+ "nativeBackboneDocumentIndexCommitMs",
361
+ "nativeBackboneDocumentIndexContextEncodeMs",
362
+ "nativeBackboneDocumentIndexExtractMs",
363
+ "nativeBackboneDocumentIndexValueBuildMs",
364
+ "nativeBackboneDocumentIndexPutMs",
365
+ "nativeBackboneDocumentValuePutMs",
366
+ "nativeBackboneDocumentIndexTrimDeleteMs",
367
+ "nativeBackboneResultRowMs",
368
+ "nativeLogCryptoVerifyMs",
369
+ "nativeLogCryptoSignableBytes",
370
+ "nativeLogCryptoStorageBytes",
371
+ "nativeLogCryptoChecksum",
372
+ "nativeGraphPrepareEntryCommitMs",
373
+ "nativeSharedLogCommitCoordinatesMs",
374
+ "nativeBackboneCommitCoordinatesMs",
375
+ "logAppendNativeCommitOnlyMs",
376
+ "logAppendNativeKnownNoNextCommitOnlyMs",
377
+ "logGetNextsForAppendMs",
378
+ "logCreateNativeAppendChainMs",
379
+ "logPutNativeCommittedAppendMs",
380
+ "logPutAppendEntriesMs",
381
+ "logTrimMs",
382
+ "logTrimUnfilteredLengthMs",
383
+ "logConsumeNativeTrimmedEntriesMs",
384
+ "remoteBlockPutKnownMs",
385
+ "remoteBlockNotifyStoredMs",
386
+ ]);
387
+ const nativeBackboneProfileKeys = new Set([
388
+ "nativeBackboneStorageAppendInnerMs",
389
+ "nativeBackboneInputCopyMs",
390
+ "nativeBackboneLogTotalMs",
391
+ "nativeBackboneLogNextCloneMs",
392
+ "nativeBackboneLogEntryCoreMs",
393
+ "nativeBackboneLogEncodeMetaMs",
394
+ "nativeBackboneLogEncodePayloadMs",
395
+ "nativeBackboneLogEncodeSignableMs",
396
+ "nativeBackboneLogSignMs",
397
+ "nativeBackboneLogEncodeSignatureMs",
398
+ "nativeBackboneLogEncodeStorageMs",
399
+ "nativeBackboneLogCidMs",
400
+ "nativeBackboneLogCidHashMs",
401
+ "nativeBackboneLogCidStringMs",
402
+ "nativeBackboneLogIndexEntryMs",
403
+ "nativeBackboneLogFactsMs",
404
+ "nativeBackboneLogBlockPutMs",
405
+ "nativeBackboneLogGraphPutMs",
406
+ "nativeBackboneLogTrimMs",
407
+ "nativeBackboneEntryRowMs",
408
+ "nativeBackboneTrimRowsMs",
409
+ "nativeBackboneHashNumberMs",
410
+ "nativeBackboneCoordinatePlanMs",
411
+ "nativeBackboneCoordinateCoreMs",
412
+ "nativeBackboneCoordinateFieldsBuildMs",
413
+ "nativeBackboneCoordinateValueEncodeMs",
414
+ "nativeBackboneCoordinateJournalPutMs",
415
+ "nativeBackboneCoordinateIndexPutMs",
416
+ "nativeBackboneCoordinateValuePutMs",
417
+ "nativeBackboneCoordinateDeleteMs",
418
+ "nativeBackboneDocumentIndexCommitMs",
419
+ "nativeBackboneDocumentIndexContextEncodeMs",
420
+ "nativeBackboneDocumentIndexExtractMs",
421
+ "nativeBackboneDocumentIndexValueBuildMs",
422
+ "nativeBackboneDocumentIndexPutMs",
423
+ "nativeBackboneDocumentValuePutMs",
424
+ "nativeBackboneDocumentIndexTrimDeleteMs",
425
+ "nativeBackboneResultRowMs",
426
+ ]);
427
+ const shouldIncludeProfileKey = (key) => {
428
+ const profileKey = key;
429
+ if (nativeBackboneProfileKeys.has(profileKey)) {
430
+ return profileNativeBackbone;
431
+ }
432
+ return profileDeep || !deepProfileKeys.has(profileKey);
433
+ };
434
+ const emptyProfile = () => ({
435
+ serializeMs: 0,
436
+ existingHeadLookupMs: 0,
437
+ documentCommitPlainPutPlanMs: 0,
438
+ documentCommitNativeAppendMs: 0,
439
+ documentCreateAppendCommitFactsMs: 0,
440
+ documentHandlePreparedCommitMs: 0,
441
+ sharedAppendMs: 0,
442
+ sharedProcessLocalAppendMs: 0,
443
+ sharedProcessLocalAppendBatchMs: 0,
444
+ sharedPlanEntryLeadersMs: 0,
445
+ sharedLeaderContextMs: 0,
446
+ sharedCoordinatePrepareMs: 0,
447
+ sharedPersistCoordinateMs: 0,
448
+ sharedApplyPreparedFactsMs: 0,
449
+ sharedCreateAppendCommitMs: 0,
450
+ sharedMaterializeEntryMs: 0,
451
+ sharedCoordinateIndexPutMs: 0,
452
+ sharedNativeBackboneStorageTransactionMs: 0,
453
+ nativeBackbonePrepareStorageAppendMs: 0,
454
+ nativeBackbonePrepareNoNextStorageAppendMs: 0,
455
+ nativeBackbonePrepareStorageAppendWithNextMs: 0,
456
+ nativeBackbonePrepareCommittedNoNextStorageAppendMs: 0,
457
+ nativeBackbonePrepareCommittedStorageAppendMs: 0,
458
+ nativeBackboneStorageAppendInnerMs: 0,
459
+ nativeBackboneInputCopyMs: 0,
460
+ nativeBackboneLogTotalMs: 0,
461
+ nativeBackboneLogNextCloneMs: 0,
462
+ nativeBackboneLogEntryCoreMs: 0,
463
+ nativeBackboneLogEncodeMetaMs: 0,
464
+ nativeBackboneLogEncodePayloadMs: 0,
465
+ nativeBackboneLogEncodeSignableMs: 0,
466
+ nativeBackboneLogSignMs: 0,
467
+ nativeBackboneLogEncodeSignatureMs: 0,
468
+ nativeBackboneLogEncodeStorageMs: 0,
469
+ nativeBackboneLogCidMs: 0,
470
+ nativeBackboneLogCidHashMs: 0,
471
+ nativeBackboneLogCidStringMs: 0,
472
+ nativeBackboneLogIndexEntryMs: 0,
473
+ nativeBackboneLogFactsMs: 0,
474
+ nativeBackboneLogBlockPutMs: 0,
475
+ nativeBackboneLogGraphPutMs: 0,
476
+ nativeBackboneLogTrimMs: 0,
477
+ nativeBackboneEntryRowMs: 0,
478
+ nativeBackboneTrimRowsMs: 0,
479
+ nativeBackboneHashNumberMs: 0,
480
+ nativeBackboneCoordinatePlanMs: 0,
481
+ nativeBackboneCoordinateCoreMs: 0,
482
+ nativeBackboneCoordinateFieldsBuildMs: 0,
483
+ nativeBackboneCoordinateValueEncodeMs: 0,
484
+ nativeBackboneCoordinateJournalPutMs: 0,
485
+ nativeBackboneCoordinateIndexPutMs: 0,
486
+ nativeBackboneCoordinateValuePutMs: 0,
487
+ nativeBackboneCoordinateDeleteMs: 0,
488
+ nativeBackboneDocumentIndexCommitMs: 0,
489
+ nativeBackboneDocumentIndexContextEncodeMs: 0,
490
+ nativeBackboneDocumentIndexExtractMs: 0,
491
+ nativeBackboneDocumentIndexValueBuildMs: 0,
492
+ nativeBackboneDocumentIndexPutMs: 0,
493
+ nativeBackboneDocumentValuePutMs: 0,
494
+ nativeBackboneDocumentIndexTrimDeleteMs: 0,
495
+ nativeBackboneResultRowMs: 0,
496
+ nativeLogCryptoVerifyMs: 0,
497
+ nativeLogCryptoSignableBytes: 0,
498
+ nativeLogCryptoStorageBytes: 0,
499
+ nativeLogCryptoChecksum: 0,
500
+ nativeGraphPrepareEntryCommitMs: 0,
501
+ nativeSharedLogCommitCoordinatesMs: 0,
502
+ nativeBackboneCommitCoordinatesMs: 0,
503
+ logAppendMs: 0,
504
+ logAppendNativeCommitOnlyMs: 0,
505
+ logAppendNativeKnownNoNextCommitOnlyMs: 0,
506
+ logGetNextsForAppendMs: 0,
507
+ logCreateNativeAppendChainMs: 0,
508
+ logPutNativeCommittedAppendMs: 0,
509
+ logPutAppendEntriesMs: 0,
510
+ logTrimMs: 0,
511
+ logTrimUnfilteredLengthMs: 0,
512
+ logConsumeNativeTrimmedEntriesMs: 0,
513
+ remoteBlockPutKnownMs: 0,
514
+ remoteBlockNotifyStoredMs: 0,
515
+ documentIndexPutMs: 0,
516
+ documentIndexTransformMs: 0,
517
+ documentBackendIndexPutMs: 0,
518
+ totalPutMs: 0,
151
519
  });
152
520
  const payload = new Uint8Array(payloadBytes);
153
521
  for (let i = 0; i < payload.length; i++) {
154
522
  payload[i] = i % 256;
155
523
  }
524
+ const writeU32 = (out, value) => {
525
+ out.push(value & 0xff, (value >> 8) & 0xff, (value >> 16) & 0xff, value >>> 24);
526
+ };
527
+ const writeString = (out, value) => {
528
+ const bytes = new TextEncoder().encode(value);
529
+ writeU32(out, bytes.byteLength);
530
+ out.push(...bytes);
531
+ };
532
+ const nativeCeilingContextSchemaIr = () => {
533
+ const out = [1, 14];
534
+ writeU32(out, 1);
535
+ out.push(0);
536
+ writeU32(out, 5);
537
+ writeString(out, "created");
538
+ writeU32(out, 1);
539
+ writeU32(out, 101);
540
+ out.push(4);
541
+ writeString(out, "modified");
542
+ writeU32(out, 2);
543
+ writeU32(out, 102);
544
+ out.push(4);
545
+ writeString(out, "head");
546
+ writeU32(out, 3);
547
+ writeU32(out, 103);
548
+ out.push(12);
549
+ writeString(out, "gid");
550
+ writeU32(out, 4);
551
+ writeU32(out, 104);
552
+ out.push(12);
553
+ writeString(out, "size");
554
+ writeU32(out, 5);
555
+ writeU32(out, 105);
556
+ out.push(3);
557
+ return Uint8Array.from(out);
558
+ };
559
+ const fromHex = (hex) => Uint8Array.from(hex.match(/.{2}/g)?.map((byte) => Number.parseInt(byte, 16)) ?? []);
560
+ const nativeBackbonePrivateKey = fromHex("9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60");
561
+ const nativeBackbonePublicKey = fromHex("d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a");
156
562
  let idCounter = 0;
157
- const suite = new Bench({
158
- name: "document-put",
159
- warmupIterations: Number.isFinite(warmupIterations) ? warmupIterations : 0,
160
- iterations: typeof iterations === "number" && Number.isFinite(iterations)
161
- ? iterations
162
- : undefined,
563
+ const createDocument = () => new Document({
564
+ id: String(idCounter++),
565
+ name: "hello",
566
+ number: 1n,
567
+ bytes: payload,
568
+ signer: currentSignerFieldBytes,
163
569
  });
164
- suite.add("put (unique)", async () => {
165
- const doc = new Document({
166
- id: String(idCounter++),
167
- name: "hello",
168
- number: 1n,
169
- bytes: payload,
570
+ const time = async (profile, key, fn) => {
571
+ const started = performance.now();
572
+ try {
573
+ return await fn();
574
+ }
575
+ finally {
576
+ profile[key] += performance.now() - started;
577
+ }
578
+ };
579
+ const isPromiseLike = (value) => !!value && typeof value.then === "function";
580
+ const addProfileTime = (profile, profileKey, durationMs) => {
581
+ const keys = typeof profileKey === "string" ? [profileKey] : profileKey;
582
+ for (const key of keys) {
583
+ profile[key] += durationMs;
584
+ }
585
+ };
586
+ const patchAsyncMethod = (target, key, profile, profileKey) => {
587
+ const original = target[key];
588
+ if (typeof original !== "function") {
589
+ return () => { };
590
+ }
591
+ target[key] = function patched(...args) {
592
+ const started = performance.now();
593
+ try {
594
+ const result = original.apply(this, args);
595
+ if (isPromiseLike(result)) {
596
+ return result.finally(() => {
597
+ addProfileTime(profile, profileKey, performance.now() - started);
598
+ });
599
+ }
600
+ addProfileTime(profile, profileKey, performance.now() - started);
601
+ return result;
602
+ }
603
+ catch (error) {
604
+ addProfileTime(profile, profileKey, performance.now() - started);
605
+ throw error;
606
+ }
607
+ };
608
+ return () => {
609
+ target[key] = original;
610
+ };
611
+ };
612
+ const timeSync = (profile, key, fn) => {
613
+ const started = performance.now();
614
+ try {
615
+ return fn();
616
+ }
617
+ finally {
618
+ addProfileTime(profile, key, performance.now() - started);
619
+ }
620
+ };
621
+ const patchSyncMethod = (target, key, profile, profileKey) => {
622
+ const original = target[key];
623
+ if (typeof original !== "function") {
624
+ return () => { };
625
+ }
626
+ target[key] = function patched(...args) {
627
+ return timeSync(profile, profileKey, () => original.apply(this, args));
628
+ };
629
+ return () => {
630
+ target[key] = original;
631
+ };
632
+ };
633
+ const createNodeCoordinatePersistence = async (buffered, direct) => {
634
+ const [{ mkdtemp, rm }, { tmpdir }, { join }] = await Promise.all([
635
+ import("node:fs/promises"),
636
+ import("node:os"),
637
+ import("node:path"),
638
+ ]);
639
+ const directory = await mkdtemp(join(tmpdir(), "peerbit-doc-coordinate-wal-"));
640
+ const directPersistence = direct
641
+ ? buffered
642
+ ? createBufferedNativeBackboneNodeCoordinatePersistence(directory, {
643
+ flushMaxPendingBytes: coordinateWalFlushBytes,
644
+ writeBufferMaxBytes: coordinateWalFlushBytes,
645
+ ...(coordinateWalFlushIntervalMs != null
646
+ ? { flushIntervalMs: coordinateWalFlushIntervalMs }
647
+ : {}),
648
+ })
649
+ : new NativeBackboneNodeCoordinatePersistence(directory)
650
+ : undefined;
651
+ const store = direct
652
+ ? undefined
653
+ : new NativeBackboneNodeCoordinatePersistenceStore(directory);
654
+ const persistence = directPersistence ??
655
+ (buffered
656
+ ? createBufferedNativeBackboneCoordinatePersistence(store, {
657
+ flushMaxPendingBytes: coordinateWalFlushBytes,
658
+ maxBufferedBytes: coordinateWalFlushBytes,
659
+ ...(coordinateWalFlushIntervalMs != null
660
+ ? { flushIntervalMs: coordinateWalFlushIntervalMs }
661
+ : {}),
662
+ })
663
+ : {
664
+ store: store,
665
+ flushOnAppend: true,
666
+ });
667
+ return {
668
+ persistence,
669
+ cleanup: async () => {
670
+ await directPersistence?.close?.();
671
+ await store?.close();
672
+ await rm(directory, { recursive: true, force: true });
673
+ },
674
+ };
675
+ };
676
+ const openScenario = async (name) => {
677
+ const baseName = scenarioBaseName(name);
678
+ const useNativeMode = scenarioUsesNativeMode(name);
679
+ const rustOptions = baseName === "native-block-store" ||
680
+ baseName === "rust-peerbit" ||
681
+ baseName === "rust-peerbit-transient-index" ||
682
+ baseName === "rust-peerbit-backbone"
683
+ ? createRustPeerbitOptions()
684
+ : undefined;
685
+ const session = await TestSession.connected(1, {
686
+ ...(rustOptions ? { storage: rustOptions.storage } : {}),
687
+ indexer: baseName === "simple-index"
688
+ ? createSimpleIndexer
689
+ : baseName === "sqlite-index"
690
+ ? createSqliteIndexer
691
+ : baseName === "rust-peerbit"
692
+ ? rustOptions?.indexer
693
+ : baseName === "rust-peerbit-transient-index"
694
+ ? () => rustOptions.indexer(undefined)
695
+ : baseName === "rust-peerbit-backbone"
696
+ ? () => rustOptions.indexer(undefined)
697
+ : undefined,
170
698
  });
171
- await store.docs.put(doc, { unique: true });
172
- });
173
- try {
174
- await suite.run();
175
- if (process.env.BENCH_JSON === "1") {
176
- const tasks = suite.tasks.map((task) => ({
177
- name: task.name,
178
- hz: task.result?.hz ?? null,
179
- mean_ms: task.result?.mean ?? null,
180
- rme: task.result?.rme ?? null,
181
- samples: task.result?.samples?.length ?? null,
182
- }));
183
- process.stdout.write(JSON.stringify({
184
- name: suite.name,
185
- tasks,
186
- meta: {
187
- payloadBytes,
188
- warmupIterations,
189
- iterations: iterations ?? null,
699
+ const coordinateWal = baseName === "rust-peerbit-backbone" &&
700
+ (scenarioUsesCoordinateWal(name) || useNativeMode)
701
+ ? await createNodeCoordinatePersistence(scenarioUsesBufferedCoordinateWal(name) || useNativeMode, scenarioUsesDirectCoordinateWal(name))
702
+ : undefined;
703
+ const store = new TestStore({
704
+ docs: new Documents(),
705
+ });
706
+ const client = session.peers[0];
707
+ currentSignerFieldBytes = scenarioUsesPolicyPutSignedField(name)
708
+ ? session.peers[0].identity.publicKey.bytes
709
+ : undefined;
710
+ const indexOptions = scenarioUsesTransformIdentity(name)
711
+ ? { transform: transform.identity() }
712
+ : scenarioUsesTransformPick(name)
713
+ ? {
714
+ type: PickIndexable,
715
+ transform: transform.pick(["id", "name"]),
716
+ }
717
+ : scenarioUsesTransformProjectContext(name)
718
+ ? {
719
+ type: ProjectIndexable,
720
+ transform: transform.project({
721
+ id: transform.field("id"),
722
+ created: transform.context("created"),
723
+ signer: transform.field("signer"),
724
+ }),
725
+ }
726
+ : scenarioUsesTransformArbitrary(name)
727
+ ? {
728
+ type: PickIndexable,
729
+ transform: (document) => new PickIndexable({
730
+ id: document.id,
731
+ name: document.name,
732
+ }),
733
+ }
734
+ : undefined;
735
+ try {
736
+ await client.open(store, {
737
+ args: {
738
+ ...(useNativeMode ? { mode: "native" } : {}),
739
+ replicate: scenarioUsesNativeModeReplicated(name) ||
740
+ (!useNativeMode && !scenarioUsesLocalStore(name))
741
+ ? { factor: 1 }
742
+ : false,
743
+ ...(indexOptions ? { index: indexOptions } : {}),
744
+ ...(scenarioUsesPolicyAllowAll(name)
745
+ ? { canPerform: policy.allowAll() }
746
+ : scenarioUsesPolicySignedPublicKey(name)
747
+ ? {
748
+ canPerform: policy.signedByPublicKey(session.peers[0].identity.publicKey),
749
+ }
750
+ : scenarioUsesPolicyPutSignedPublicKey(name)
751
+ ? {
752
+ canPerform: policy.put(policy.signedByPublicKey(session.peers[0].identity.publicKey)),
753
+ }
754
+ : scenarioUsesPolicyPutSignedField(name)
755
+ ? {
756
+ canPerform: policy.put(policy.signedByField("signer")),
757
+ }
758
+ : scenarioUsesPolicyPutSameSigner(name)
759
+ ? {
760
+ canPerform: policy.put(policy.sameSignersAsPrevious()),
761
+ }
762
+ : scenarioUsesCanPerformAllowAll(name)
763
+ ? { canPerform: () => true }
764
+ : {}),
765
+ nativeGraph: baseName === "native-graph" ||
766
+ baseName === "rust-peerbit" ||
767
+ baseName === "rust-peerbit-transient-index" ||
768
+ baseName === "rust-peerbit-backbone",
769
+ ...(baseName === "rust-peerbit-backbone"
770
+ ? {
771
+ nativeBackbone: {
772
+ optional: false,
773
+ ...(scenarioUsesNativeBackboneDocumentIndex(name) ||
774
+ useNativeMode
775
+ ? { documentIndex: true }
776
+ : {}),
777
+ ...(coordinateWal
778
+ ? { coordinatePersistence: coordinateWal.persistence }
779
+ : {}),
780
+ },
781
+ }
782
+ : {}),
783
+ ...(scenarioDisablesTrim(name) ||
784
+ (scenarioUsesLocalStore(name) && !scenarioUsesTrim(name))
785
+ ? {}
786
+ : {
787
+ log: {
788
+ trim: scenarioTrimOptions(name),
789
+ },
790
+ }),
190
791
  },
191
- }, null, 2));
792
+ });
793
+ return { session, store, cleanup: coordinateWal?.cleanup };
192
794
  }
193
- else {
194
- console.table(suite.table());
795
+ catch (error) {
796
+ await coordinateWal?.cleanup();
797
+ await session.stop();
798
+ throw error;
195
799
  }
800
+ };
801
+ const runPuts = async (store, count, scenario, profile) => {
802
+ const canAppend = () => true;
803
+ const useNativeMode = scenarioUsesNativeMode(scenario);
804
+ const appendOptions = {
805
+ ...(useNativeMode ? {} : { replicate: false, target: "none" }),
806
+ ...(scenarioUsesUniquePuts(scenario) ? { unique: true } : {}),
807
+ ...(scenarioBaseName(scenario) === "compat-path" ? { canAppend } : {}),
808
+ };
809
+ if (scenarioUsesPutMany(scenario)) {
810
+ if (scenarioUsesUpdatePuts(scenario)) {
811
+ const docs = Array.from({ length: count }, (_, index) => new Document({
812
+ id: `update-many-${idCounter++}-${index}`,
813
+ name: "before",
814
+ number: 1n,
815
+ bytes: payload,
816
+ signer: currentSignerFieldBytes,
817
+ }));
818
+ await store.docs.putMany(docs, { ...appendOptions, unique: true });
819
+ const updated = docs.map((doc, index) => new Document({
820
+ id: doc.id,
821
+ name: `updated-${index}`,
822
+ number: BigInt(index),
823
+ bytes: payload,
824
+ signer: currentSignerFieldBytes,
825
+ }));
826
+ if (profile) {
827
+ await time(profile, "totalPutMs", () => store.docs.putMany(updated, appendOptions));
828
+ }
829
+ else {
830
+ await store.docs.putMany(updated, appendOptions);
831
+ }
832
+ return;
833
+ }
834
+ const docs = Array.from({ length: count }, () => createDocument());
835
+ if (profile) {
836
+ await time(profile, "totalPutMs", () => store.docs.putMany(docs, appendOptions));
837
+ }
838
+ else {
839
+ await store.docs.putMany(docs, appendOptions);
840
+ }
841
+ return;
842
+ }
843
+ if (scenarioUsesUpdatePuts(scenario)) {
844
+ const id = String(idCounter++);
845
+ for (let i = 0; i < count; i++) {
846
+ const doc = new Document({
847
+ id,
848
+ name: `hello-${i}`,
849
+ number: BigInt(i),
850
+ bytes: payload,
851
+ signer: currentSignerFieldBytes,
852
+ });
853
+ if (profile) {
854
+ await time(profile, "totalPutMs", () => store.docs.put(doc, appendOptions));
855
+ }
856
+ else {
857
+ await store.docs.put(doc, appendOptions);
858
+ }
859
+ }
860
+ return;
861
+ }
862
+ for (let i = 0; i < count; i++) {
863
+ const doc = createDocument();
864
+ if (profile) {
865
+ await time(profile, "totalPutMs", () => store.docs.put(doc, appendOptions));
866
+ }
867
+ else {
868
+ await store.docs.put(doc, appendOptions);
869
+ }
870
+ }
871
+ };
872
+ const runScenario = async (name) => {
873
+ const { session, store, cleanup } = await openScenario(name);
874
+ let row;
875
+ try {
876
+ await runPuts(store, warmupIterations, name);
877
+ const profile = emptyProfile();
878
+ const backendIndex = store.docs.index.index;
879
+ const restores = [
880
+ patchAsyncMethod(store.docs, "getLocalIndexedContext", profile, "existingHeadLookupMs"),
881
+ patchAsyncMethod(store.docs, "commitPlainPutPlan", profile, "documentCommitPlainPutPlanMs"),
882
+ patchAsyncMethod(store.docs, "commitNativeDocumentAppend", profile, "documentCommitNativeAppendMs"),
883
+ patchAsyncMethod(store.docs, "createDocumentAppendCommitFacts", profile, "documentCreateAppendCommitFactsMs"),
884
+ patchAsyncMethod(store.docs, "handlePreparedPlainPutCommit", profile, "documentHandlePreparedCommitMs"),
885
+ patchAsyncMethod(store.docs.log, "append", profile, "sharedAppendMs"),
886
+ patchAsyncMethod(store.docs.log, "appendLocallyValidated", profile, "sharedAppendMs"),
887
+ patchAsyncMethod(store.docs.log, "appendLocallyPrepared", profile, "sharedAppendMs"),
888
+ patchAsyncMethod(store.docs.log, "appendLocallyPreparedPayloadCommitOnly", profile, "sharedAppendMs"),
889
+ patchAsyncMethod(store.docs.log, "appendStrictNativeDocumentPayloadCommitOnly", profile, "sharedAppendMs"),
890
+ patchAsyncMethod(store.docs.log, "appendLocallyPreparedManyIndependent", profile, "sharedAppendMs"),
891
+ patchAsyncMethod(store.docs.log.log, "append", profile, "logAppendMs"),
892
+ patchAsyncMethod(store.docs.log.log, "appendLocallyPrepared", profile, "logAppendMs"),
893
+ patchAsyncMethod(store.docs.log.log, "appendLocallyPreparedCommitOnly", profile, "logAppendMs"),
894
+ patchAsyncMethod(store.docs.log.log, "appendLocallyPreparedNativeNoNextCommitOnly", profile, "logAppendMs"),
895
+ patchAsyncMethod(store.docs.log.log, "appendLocallyPreparedManyIndependent", profile, "logAppendMs"),
896
+ patchAsyncMethod(store.docs.index, "transformer", profile, "documentIndexTransformMs"),
897
+ patchAsyncMethod(backendIndex, typeof backendIndex.putWithContext === "function"
898
+ ? "putWithContext"
899
+ : "put", profile, "documentBackendIndexPutMs"),
900
+ patchAsyncMethod(backendIndex, typeof backendIndex.putWithContextBatch === "function"
901
+ ? "putWithContextBatch"
902
+ : "putBatch", profile, "documentBackendIndexPutMs"),
903
+ patchAsyncMethod(backendIndex, "putStoredContextualEncodedValue", profile, "documentBackendIndexPutMs"),
904
+ patchAsyncMethod(store.docs.index, "putWithContext", profile, "documentIndexPutMs"),
905
+ patchAsyncMethod(store.docs.index, "_putStoredIdentityWithContext", profile, "documentIndexPutMs"),
906
+ patchAsyncMethod(store.docs.index, "_putPreparedNativeBackboneDocumentIndexWithContext", profile, "documentIndexPutMs"),
907
+ patchAsyncMethod(store.docs.index, "_putIdentityWithContext", profile, "documentIndexPutMs"),
908
+ patchAsyncMethod(store.docs.index, "putManyWithContext", profile, "documentIndexPutMs"),
909
+ patchAsyncMethod(store.docs.index, "_putManyIdentityWithContext", profile, "documentIndexPutMs"),
910
+ patchAsyncMethod(store.docs.index, "_putManyPreparedNativeBackboneDocumentIndexStored", profile, "documentIndexPutMs"),
911
+ ];
912
+ if (profileDeep) {
913
+ restores.push(patchAsyncMethod(store.docs.log, "processLocalAppend", profile, "sharedProcessLocalAppendMs"), patchAsyncMethod(store.docs.log, "processNativePreparedTargetNoneAppendTransaction", profile, "sharedProcessLocalAppendMs"), patchAsyncMethod(store.docs.log, "processLocalAppendManyNativePlanned", profile, "sharedProcessLocalAppendBatchMs"), patchAsyncMethod(store.docs.log, "planEntryLeaders", profile, "sharedPlanEntryLeadersMs"), patchAsyncMethod(store.docs.log, "createLeaderSelectionContext", profile, "sharedLeaderContextMs"), patchAsyncMethod(store.docs.log, "planNativeLocalAppendEntry", profile, "sharedPlanEntryLeadersMs"), patchAsyncMethod(store.docs.log, "planNativeLocalAppendFacts", profile, "sharedPlanEntryLeadersMs"), patchAsyncMethod(store.docs.log, "planNativeAppendEntry", profile, "sharedPlanEntryLeadersMs"), patchAsyncMethod(store.docs.log, "planNativeAppendFacts", profile, "sharedPlanEntryLeadersMs"), patchSyncMethod(store.docs.log, "createCoordinatePersistenceEntryFromNativePlanFacts", profile, "sharedCoordinatePrepareMs"), patchSyncMethod(store.docs.log, "createCoordinatePersistenceEntryFromNativePlan", profile, "sharedCoordinatePrepareMs"), patchAsyncMethod(store.docs.log, "persistCoordinate", profile, "sharedPersistCoordinateMs"), patchAsyncMethod(store.docs.log, "persistPreparedCoordinate", profile, "sharedPersistCoordinateMs"), patchAsyncMethod(store.docs.log, "persistPreparedCoordinateNativeTransaction", profile, "sharedPersistCoordinateMs"), patchAsyncMethod(store.docs.log, "persistPreparedBackboneCoordinateNativeTransaction", profile, "sharedPersistCoordinateMs"), patchAsyncMethod(store.docs.log, "persistBackboneCoordinateFieldsNativeTransaction", profile, "sharedPersistCoordinateMs"), patchAsyncMethod(store.docs.log, "persistCoordinatesBatch", profile, "sharedPersistCoordinateMs"), patchSyncMethod(store.docs.log, "applyPreparedAppendFactsWithDeferredCoordinateDeletes", profile, "sharedApplyPreparedFactsMs"), patchSyncMethod(store.docs.log, "createPreparedLocalAppendCommitFromFacts", profile, "sharedCreateAppendCommitMs"), patchSyncMethod(store.docs.log, "materializePreparedAppendResultEntry", profile, "sharedMaterializeEntryMs"), patchAsyncMethod(store.docs.log.entryCoordinatesIndex ?? {}, "putSharedLogCoordinateFieldsEncodedAndDeleteHashesNoReturn", profile, "sharedCoordinateIndexPutMs"), patchAsyncMethod(store.docs.log.entryCoordinatesIndex ?? {}, "putSharedLogCoordinateFieldsAndDeleteHashesNoReturn", profile, "sharedCoordinateIndexPutMs"), patchAsyncMethod(store.docs.log, "appendLocallyPreparedPayloadNativeBackboneStorageTransaction", profile, "sharedNativeBackboneStorageTransactionMs"), patchSyncMethod(store.docs.log._nativeBackbone ?? {}, "preparePlainStorageAppendTransaction", profile, [
914
+ "nativeBackbonePrepareStorageAppendMs",
915
+ "nativeBackbonePrepareStorageAppendWithNextMs",
916
+ ]), patchSyncMethod(store.docs.log._nativeBackbone ?? {}, "preparePlainNoNextStorageAppendTransaction", profile, [
917
+ "nativeBackbonePrepareStorageAppendMs",
918
+ "nativeBackbonePrepareNoNextStorageAppendMs",
919
+ ]), patchSyncMethod(store.docs.log._nativeBackbone ?? {}, "preparePlainCommittedStorageAppendTransaction", profile, [
920
+ "nativeBackbonePrepareStorageAppendMs",
921
+ "nativeBackbonePrepareCommittedStorageAppendMs",
922
+ ]), patchSyncMethod(store.docs.log._nativeBackbone ?? {}, "preparePlainCommittedNoNextStorageAppendTransaction", profile, [
923
+ "nativeBackbonePrepareStorageAppendMs",
924
+ "nativeBackbonePrepareCommittedNoNextStorageAppendMs",
925
+ ]), patchSyncMethod(store.docs.log._nativeBackbone ?? {}, "preparePlainCommittedNoNextStorageAppendDocumentIndexCompactTransaction", profile, [
926
+ "nativeBackbonePrepareStorageAppendMs",
927
+ "nativeBackbonePrepareCommittedNoNextStorageAppendMs",
928
+ ]), patchSyncMethod(store.docs.log._nativeBackbone?.graph ?? {}, "prepareEntryV0PlainEntryCommit", profile, "nativeGraphPrepareEntryCommitMs"), patchSyncMethod(store.docs.log.log.entryIndex.properties?.nativeGraph
929
+ ?.graph ?? {}, "prepareEntryV0PlainEntryCommit", profile, "nativeGraphPrepareEntryCommitMs"), patchSyncMethod(store.docs.log._nativeSharedLogState ?? {}, "commitEntryCoordinates", profile, "nativeSharedLogCommitCoordinatesMs"), patchSyncMethod(store.docs.log._nativeBackbone ?? {}, "commitEntryCoordinates", profile, "nativeBackboneCommitCoordinatesMs"), patchAsyncMethod(store.docs.log.remoteBlocks ?? {}, "putKnown", profile, "remoteBlockPutKnownMs"), patchAsyncMethod(store.docs.log.remoteBlocks ?? {}, typeof store.docs.log.remoteBlocks
930
+ ?.notifyStoredDeferred === "function"
931
+ ? "notifyStoredDeferred"
932
+ : "notifyStored", profile, "remoteBlockNotifyStoredMs"), patchAsyncMethod(store.docs.log.log, "getNextsForAppend", profile, "logGetNextsForAppendMs"), patchAsyncMethod(store.docs.log.log, "appendLocallyPreparedNativeCommitOnly", profile, "logAppendNativeCommitOnlyMs"), patchAsyncMethod(store.docs.log.log, "appendLocallyPreparedNativeKnownNoNextCommitOnly", profile, "logAppendNativeKnownNoNextCommitOnlyMs"), patchAsyncMethod(store.docs.log.log, "createNativePlainAppendChain", profile, "logCreateNativeAppendChainMs"), patchAsyncMethod(store.docs.log.log, "createNativePlainAppendCommitOnly", profile, "logCreateNativeAppendChainMs"), patchAsyncMethod(store.docs.log.log, "createNativePlainAppendEntriesBatch", profile, "logCreateNativeAppendChainMs"), patchAsyncMethod(store.docs.log.log.entryIndex, "putNativeCommittedAppend", profile, "logPutNativeCommittedAppendMs"), patchAsyncMethod(store.docs.log.log.entryIndex, "putNativeCommittedAppendFacts", profile, "logPutNativeCommittedAppendMs"), patchAsyncMethod(store.docs.log.log.entryIndex, "consumeNativeTrimmedEntriesMaybe", profile, "logConsumeNativeTrimmedEntriesMs"), patchAsyncMethod(store.docs.log.log, "putAppendEntries", profile, "logPutAppendEntriesMs"), patchAsyncMethod(store.docs.log.log, "trim", profile, "logTrimMs"), patchAsyncMethod(store.docs.log.log._trim, "trimUnfilteredLength", profile, "logTrimUnfilteredLengthMs"));
933
+ }
934
+ const nativeBackbone = store.docs.log._nativeBackbone;
935
+ if (profileNativeBackbone && nativeBackbone?.setAppendProfileEnabled) {
936
+ nativeBackbone.resetAppendProfile?.();
937
+ nativeBackbone.setAppendProfileEnabled(true);
938
+ }
939
+ const serializeStarted = performance.now();
940
+ for (let i = 0; i < iterations; i++) {
941
+ serialize(createDocument());
942
+ }
943
+ profile.serializeMs = performance.now() - serializeStarted;
944
+ try {
945
+ await runPuts(store, iterations, name, profile);
946
+ if (profileNativeBackbone && nativeBackbone?.appendProfile) {
947
+ Object.assign(profile, nativeBackbone.appendProfile());
948
+ }
949
+ }
950
+ finally {
951
+ nativeBackbone?.setAppendProfileEnabled?.(false);
952
+ for (const restore of restores.reverse()) {
953
+ restore();
954
+ }
955
+ }
956
+ row = {
957
+ name,
958
+ iterations,
959
+ payloadBytes,
960
+ opsPerSecond: Math.round((iterations / profile.totalPutMs) * 1000),
961
+ cleanupMs: 0,
962
+ ...Object.fromEntries(Object.entries(profile)
963
+ .filter(([key]) => shouldIncludeProfileKey(key))
964
+ .map(([key, value]) => [key, Math.round(value * 100) / 100])),
965
+ };
966
+ }
967
+ finally {
968
+ const cleanupStarted = performance.now();
969
+ try {
970
+ try {
971
+ await store.drop();
972
+ }
973
+ finally {
974
+ try {
975
+ await session.stop();
976
+ }
977
+ finally {
978
+ await cleanup?.();
979
+ }
980
+ }
981
+ }
982
+ finally {
983
+ if (row) {
984
+ row.cleanupMs =
985
+ Math.round((performance.now() - cleanupStarted) * 100) / 100;
986
+ }
987
+ }
988
+ }
989
+ if (!row) {
990
+ throw new Error(`Benchmark scenario ${name} did not produce a row`);
991
+ }
992
+ return row;
993
+ };
994
+ const runNativeCeilingScenario = async (name) => {
995
+ const session = await TestSession.disconnected(1);
996
+ const rustOptions = createRustPeerbitOptions({
997
+ storage: { nativeLogBlocks: true },
998
+ });
999
+ const blockStore = rustOptions.storage.blocksStoreFactory();
1000
+ blockStore.rm ??= (key) => blockStore.del(key);
1001
+ blockStore.rmMany ??= async (keys) => {
1002
+ await Promise.all(keys.map((key) => blockStore.rm(key)));
1003
+ return keys.length;
1004
+ };
1005
+ await blockStore.open?.();
1006
+ const log = new Log();
1007
+ await log.open(blockStore, session.peers[0].identity, {
1008
+ nativeGraph: true,
1009
+ encoding: {
1010
+ encoder: (value) => value,
1011
+ decoder: (bytes) => bytes,
1012
+ },
1013
+ trim: { type: "length", to: 100 },
1014
+ });
1015
+ const append = async (count, profile) => {
1016
+ for (let i = 0; i < count; i++) {
1017
+ const runAppend = () => log.appendLocallyPreparedCommitOnly(undefined, { meta: { next: [] } }, {
1018
+ payloadData: payload,
1019
+ includeMaterializationBytes: false,
1020
+ includeAppendFactsBytes: true,
1021
+ resolveTrimmedEntries: false,
1022
+ skipMissingNextJoin: true,
1023
+ });
1024
+ if (profile) {
1025
+ await time(profile, "totalPutMs", async () => {
1026
+ await runAppend();
1027
+ });
1028
+ }
1029
+ else {
1030
+ await runAppend();
1031
+ }
1032
+ }
1033
+ };
1034
+ try {
1035
+ await append(warmupIterations);
1036
+ const profile = emptyProfile();
1037
+ const restores = [
1038
+ patchAsyncMethod(log, "appendLocallyPreparedCommitOnly", profile, "logAppendMs"),
1039
+ patchAsyncMethod(log, "getNextsForAppend", profile, "logGetNextsForAppendMs"),
1040
+ patchAsyncMethod(log, "createNativePlainAppendCommitOnly", profile, "logCreateNativeAppendChainMs"),
1041
+ patchAsyncMethod(log.entryIndex, "putNativeCommittedAppendFacts", profile, "logPutNativeCommittedAppendMs"),
1042
+ patchAsyncMethod(log, "trim", profile, "logTrimMs"),
1043
+ patchAsyncMethod(log._trim, "trimUnfilteredLength", profile, "logTrimUnfilteredLengthMs"),
1044
+ ];
1045
+ try {
1046
+ await append(iterations, profile);
1047
+ }
1048
+ finally {
1049
+ for (const restore of restores.reverse()) {
1050
+ restore();
1051
+ }
1052
+ }
1053
+ return {
1054
+ name,
1055
+ iterations,
1056
+ payloadBytes,
1057
+ opsPerSecond: Math.round((iterations / profile.totalPutMs) * 1000),
1058
+ cleanupMs: 0,
1059
+ ...Object.fromEntries(Object.entries(profile)
1060
+ .filter(([key]) => shouldIncludeProfileKey(key))
1061
+ .map(([key, value]) => [key, Math.round(value * 100) / 100])),
1062
+ };
1063
+ }
1064
+ finally {
1065
+ await log.close();
1066
+ await blockStore.close?.();
1067
+ await session.stop();
1068
+ }
1069
+ };
1070
+ const runNativeLogCoreCeilingScenario = async (name) => {
1071
+ const { benchmarkPlainEntryV0Core, benchmarkPlainEntryV0DigestKeyCore, } = await loadNativeLogBenchmarkHelpers();
1072
+ const benchmark = name.includes("digest-key")
1073
+ ? benchmarkPlainEntryV0DigestKeyCore
1074
+ : benchmarkPlainEntryV0Core;
1075
+ await benchmark({
1076
+ clockId: nativeBackbonePublicKey,
1077
+ privateKey: nativeBackbonePrivateKey,
1078
+ publicKey: nativeBackbonePublicKey,
1079
+ iterations: warmupIterations,
1080
+ payloadData: payload,
1081
+ });
1082
+ const profile = emptyProfile();
1083
+ const result = await benchmark({
1084
+ clockId: nativeBackbonePublicKey,
1085
+ privateKey: nativeBackbonePrivateKey,
1086
+ publicKey: nativeBackbonePublicKey,
1087
+ iterations,
1088
+ payloadData: payload,
1089
+ });
1090
+ profile.totalPutMs = result.totalMs;
1091
+ profile.nativeBackboneInputCopyMs = result.inputCopyMs;
1092
+ profile.nativeBackboneLogTotalMs = result.entryCoreMs;
1093
+ profile.nativeBackboneLogEntryCoreMs = result.entryCoreMs;
1094
+ profile.nativeBackboneLogEncodeMetaMs = result.encodeMetaMs;
1095
+ profile.nativeBackboneLogEncodePayloadMs = result.encodePayloadMs;
1096
+ profile.nativeBackboneLogEncodeSignableMs = result.encodeSignableMs;
1097
+ profile.nativeBackboneLogSignMs = result.signMs;
1098
+ profile.nativeBackboneLogEncodeSignatureMs = result.encodeSignatureMs;
1099
+ profile.nativeBackboneLogEncodeStorageMs = result.encodeStorageMs;
1100
+ profile.nativeBackboneLogCidMs = result.cidMs;
1101
+ profile.nativeBackboneLogCidHashMs = result.cidHashMs;
1102
+ profile.nativeBackboneLogCidStringMs = result.cidStringMs;
1103
+ profile.nativeBackboneLogIndexEntryMs = result.indexEntryMs;
1104
+ return {
1105
+ name,
1106
+ iterations,
1107
+ payloadBytes,
1108
+ opsPerSecond: Math.round((iterations / profile.totalPutMs) * 1000),
1109
+ cleanupMs: 0,
1110
+ ...Object.fromEntries(Object.entries(profile)
1111
+ .filter(([key]) => shouldIncludeProfileKey(key))
1112
+ .map(([key, value]) => [key, Math.round(value * 100) / 100])),
1113
+ };
1114
+ };
1115
+ const runNativeLogCryptoCeilingScenario = async (name) => {
1116
+ const { benchmarkPlainEntryV0Crypto } = await loadNativeLogBenchmarkHelpers();
1117
+ await benchmarkPlainEntryV0Crypto({
1118
+ clockId: nativeBackbonePublicKey,
1119
+ privateKey: nativeBackbonePrivateKey,
1120
+ publicKey: nativeBackbonePublicKey,
1121
+ iterations: warmupIterations,
1122
+ payloadData: payload,
1123
+ });
1124
+ const profile = emptyProfile();
1125
+ const result = await benchmarkPlainEntryV0Crypto({
1126
+ clockId: nativeBackbonePublicKey,
1127
+ privateKey: nativeBackbonePrivateKey,
1128
+ publicKey: nativeBackbonePublicKey,
1129
+ iterations,
1130
+ payloadData: payload,
1131
+ });
1132
+ profile.totalPutMs = result.signMs + result.sha256Ms + result.cidStringMs;
1133
+ profile.nativeBackboneLogSignMs = result.signMs;
1134
+ profile.nativeLogCryptoVerifyMs = result.verifyMs;
1135
+ profile.nativeBackboneLogCidHashMs = result.sha256Ms;
1136
+ profile.nativeBackboneLogCidStringMs = result.cidStringMs;
1137
+ profile.nativeBackboneLogCidMs = result.sha256Ms + result.cidStringMs;
1138
+ profile.nativeLogCryptoSignableBytes = result.signableBytes;
1139
+ profile.nativeLogCryptoStorageBytes = result.storageBytes;
1140
+ profile.nativeLogCryptoChecksum = result.checksum;
1141
+ return {
1142
+ name,
1143
+ iterations,
1144
+ payloadBytes,
1145
+ opsPerSecond: Math.round((iterations / profile.totalPutMs) * 1000),
1146
+ cleanupMs: 0,
1147
+ ...Object.fromEntries(Object.entries(profile)
1148
+ .filter(([key]) => shouldIncludeProfileKey(key))
1149
+ .map(([key, value]) => [key, Math.round(value * 100) / 100])),
1150
+ };
1151
+ };
1152
+ const runNativeLogCeilingScenario = async (name) => {
1153
+ const backbone = await createNativePeerbitBackbone({
1154
+ clockId: nativeBackbonePublicKey,
1155
+ privateKey: nativeBackbonePrivateKey,
1156
+ publicKey: nativeBackbonePublicKey,
1157
+ });
1158
+ const trimLengthTo = scenarioDisablesTrim(name) ? undefined : 100;
1159
+ const append = (count, profile) => {
1160
+ for (let i = 0; i < count; i++) {
1161
+ const runAppend = () => {
1162
+ const prepared = backbone.graph.prepareEntryV0PlainEntryCommit({
1163
+ clockId: nativeBackbonePublicKey,
1164
+ privateKey: nativeBackbonePrivateKey,
1165
+ publicKey: nativeBackbonePublicKey,
1166
+ wallTime: BigInt(Date.now()),
1167
+ logical: i,
1168
+ gid: `gid-${i}`,
1169
+ payloadData: payload,
1170
+ includeMaterializationBytes: false,
1171
+ includeAppendFactsBytes: true,
1172
+ trimLengthTo,
1173
+ }, backbone.blocks);
1174
+ if (!prepared) {
1175
+ throw new Error("Native log ceiling append was not prepared");
1176
+ }
1177
+ };
1178
+ if (profile) {
1179
+ timeSync(profile, "totalPutMs", runAppend);
1180
+ }
1181
+ else {
1182
+ runAppend();
1183
+ }
1184
+ }
1185
+ };
1186
+ append(warmupIterations);
1187
+ const profile = emptyProfile();
1188
+ append(iterations, profile);
1189
+ return {
1190
+ name,
1191
+ iterations,
1192
+ payloadBytes,
1193
+ opsPerSecond: Math.round((iterations / profile.totalPutMs) * 1000),
1194
+ cleanupMs: 0,
1195
+ ...Object.fromEntries(Object.entries(profile)
1196
+ .filter(([key]) => shouldIncludeProfileKey(key))
1197
+ .map(([key, value]) => [key, Math.round(value * 100) / 100])),
1198
+ };
1199
+ };
1200
+ const runNativeBackboneCeilingScenario = async (name) => {
1201
+ const backbone = await createNativePeerbitBackbone({
1202
+ clockId: nativeBackbonePublicKey,
1203
+ privateKey: nativeBackbonePrivateKey,
1204
+ publicKey: nativeBackbonePublicKey,
1205
+ });
1206
+ const useDocumentIndex = scenarioUsesNativeBackboneDocumentIndex(name);
1207
+ if (useDocumentIndex) {
1208
+ backbone.configureDocumentSchemaIr(nativeCeilingContextSchemaIr());
1209
+ }
1210
+ const useCommittedStorageTransaction = scenarioBaseName(name) === "native-backbone-storage-ceiling";
1211
+ const trimLengthTo = scenarioDisablesTrim(name) ? undefined : 100;
1212
+ if (scenarioUsesCoordinateWal(name)) {
1213
+ backbone.setCoordinateJournalEnabled(true);
1214
+ }
1215
+ const documentValuePrefix = new Uint8Array(0);
1216
+ const append = (count, profile) => {
1217
+ for (let i = 0; i < count; i++) {
1218
+ const documentIndex = useDocumentIndex
1219
+ ? {
1220
+ key: `native-backbone-ceiling-doc-${i}`,
1221
+ valuePrefixBytes: documentValuePrefix,
1222
+ byteElementIndexLimit: 0,
1223
+ }
1224
+ : undefined;
1225
+ const appendInput = {
1226
+ wallTime: BigInt(Date.now()),
1227
+ logical: i,
1228
+ gid: `gid-${i}`,
1229
+ payloadData: payload,
1230
+ replicas: 1,
1231
+ selfHash: "native-backbone-ceiling-peer",
1232
+ trimLengthTo,
1233
+ documentIndex,
1234
+ };
1235
+ const runAppend = () => useCommittedStorageTransaction
1236
+ ? backbone.preparePlainCommittedNoNextStorageAppendTransaction(appendInput)
1237
+ : backbone.appendPlainNoNextTransaction(appendInput);
1238
+ if (profile) {
1239
+ timeSync(profile, "totalPutMs", runAppend);
1240
+ }
1241
+ else {
1242
+ runAppend();
1243
+ }
1244
+ }
1245
+ };
1246
+ const profile = emptyProfile();
1247
+ append(warmupIterations);
1248
+ if (profileNativeBackbone) {
1249
+ backbone.resetAppendProfile();
1250
+ backbone.setAppendProfileEnabled(true);
1251
+ }
1252
+ try {
1253
+ append(iterations, profile);
1254
+ if (profileNativeBackbone) {
1255
+ Object.assign(profile, backbone.appendProfile());
1256
+ }
1257
+ }
1258
+ finally {
1259
+ backbone.setAppendProfileEnabled(false);
1260
+ }
1261
+ return {
1262
+ name,
1263
+ iterations,
1264
+ payloadBytes,
1265
+ opsPerSecond: Math.round((iterations / profile.totalPutMs) * 1000),
1266
+ cleanupMs: 0,
1267
+ ...Object.fromEntries(Object.entries(profile)
1268
+ .filter(([key]) => shouldIncludeProfileKey(key))
1269
+ .map(([key, value]) => [key, Math.round(value * 100) / 100])),
1270
+ };
1271
+ };
1272
+ const runNativeBackboneLoopCeilingScenario = async (name) => {
1273
+ const { benchmarkPlainCommittedNoNextStorageAppendTransactionLoop } = await loadNativeBackboneBenchmarkHelpers();
1274
+ const backbone = await createNativePeerbitBackbone({
1275
+ clockId: nativeBackbonePublicKey,
1276
+ privateKey: nativeBackbonePrivateKey,
1277
+ publicKey: nativeBackbonePublicKey,
1278
+ });
1279
+ const useDocumentIndex = scenarioUsesNativeBackboneDocumentIndex(name);
1280
+ if (useDocumentIndex) {
1281
+ backbone.configureDocumentSchemaIr(nativeCeilingContextSchemaIr());
1282
+ }
1283
+ if (scenarioUsesCoordinateWal(name)) {
1284
+ backbone.setCoordinateJournalEnabled(true);
1285
+ }
1286
+ const trimLengthTo = scenarioDisablesTrim(name) ? undefined : 100;
1287
+ const runLoop = (count, wallTimeStart) => benchmarkPlainCommittedNoNextStorageAppendTransactionLoop(backbone, {
1288
+ iterations: count,
1289
+ wallTimeStart,
1290
+ payloadData: payload,
1291
+ replicas: 1,
1292
+ selfHash: "native-backbone-loop-ceiling-peer",
1293
+ useDocumentIndex,
1294
+ documentByteElementIndexLimit: 0,
1295
+ trimLengthTo,
1296
+ });
1297
+ runLoop(warmupIterations, Date.now());
1298
+ const profile = emptyProfile();
1299
+ if (profileNativeBackbone) {
1300
+ backbone.resetAppendProfile();
1301
+ backbone.setAppendProfileEnabled(true);
1302
+ }
1303
+ try {
1304
+ const result = runLoop(iterations, Date.now() + warmupIterations + 1);
1305
+ profile.totalPutMs = result.totalMs;
1306
+ if (profileNativeBackbone) {
1307
+ Object.assign(profile, backbone.appendProfile());
1308
+ }
1309
+ }
1310
+ finally {
1311
+ backbone.setAppendProfileEnabled(false);
1312
+ }
1313
+ return {
1314
+ name,
1315
+ iterations,
1316
+ payloadBytes,
1317
+ opsPerSecond: Math.round((iterations / profile.totalPutMs) * 1000),
1318
+ cleanupMs: 0,
1319
+ ...Object.fromEntries(Object.entries(profile)
1320
+ .filter(([key]) => shouldIncludeProfileKey(key))
1321
+ .map(([key, value]) => [key, Math.round(value * 100) / 100])),
1322
+ };
1323
+ };
1324
+ const rows = [];
1325
+ for (const name of scenarioNames) {
1326
+ const baseName = scenarioBaseName(name);
1327
+ rows.push(baseName === "native-ceiling"
1328
+ ? await runNativeCeilingScenario(name)
1329
+ : baseName === "native-log-core-ceiling" ||
1330
+ baseName === "native-log-digest-key-core-ceiling"
1331
+ ? await runNativeLogCoreCeilingScenario(name)
1332
+ : baseName === "native-log-crypto-ceiling"
1333
+ ? await runNativeLogCryptoCeilingScenario(name)
1334
+ : baseName === "native-log-ceiling"
1335
+ ? await runNativeLogCeilingScenario(name)
1336
+ : baseName === "native-backbone-ceiling" ||
1337
+ baseName === "native-backbone-storage-ceiling"
1338
+ ? await runNativeBackboneCeilingScenario(name)
1339
+ : baseName === "native-backbone-loop-ceiling"
1340
+ ? await runNativeBackboneLoopCeilingScenario(name)
1341
+ : await runScenario(name));
1342
+ }
1343
+ if (process.env.BENCH_JSON === "1") {
1344
+ process.stdout.write(JSON.stringify({
1345
+ name: "document-put",
1346
+ rows,
1347
+ meta: {
1348
+ payloadBytes,
1349
+ warmupIterations,
1350
+ iterations,
1351
+ profileDeep,
1352
+ profileNativeBackbone,
1353
+ coordinateWalFlushBytes,
1354
+ coordinateWalFlushIntervalMs,
1355
+ },
1356
+ }, null, 2));
196
1357
  }
197
- finally {
198
- await store.drop();
199
- await session.stop();
1358
+ else {
1359
+ console.table(rows);
200
1360
  }
1361
+ process.exit(process.exitCode ?? 0);
201
1362
  //# sourceMappingURL=document-put.js.map