@peerbit/native-backbone 0.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.
@@ -0,0 +1,599 @@
1
+ use js_sys::{Array, Uint8Array};
2
+ use peerbit_shared_log_rust::commit_local_append_for_gid_compact_core;
3
+ use wasm_bindgen::prelude::*;
4
+
5
+ use crate::append_tx::coordinate_plan_to_row;
6
+ use crate::documents::{
7
+ document_context_facts_to_row, document_index_append_commit, DocumentIndexAppendCommit,
8
+ };
9
+ use crate::js_interop::{
10
+ array_from_value, bytes_field, string_field, strings_from_array, strings_to_array,
11
+ trim_hashes_vec,
12
+ };
13
+ use crate::shared_log_plan::leader_samples_to_optional_rows;
14
+ use crate::NativePeerbitBackbone;
15
+
16
+ #[wasm_bindgen]
17
+ impl NativePeerbitBackbone {
18
+ #[allow(clippy::too_many_arguments)]
19
+ pub fn prepare_plain_entry_storage_facts_and_put(
20
+ &mut self,
21
+ wall_time: u64,
22
+ logical: u32,
23
+ gid: String,
24
+ next: Array,
25
+ entry_type: u8,
26
+ meta_data: JsValue,
27
+ payload_data: Uint8Array,
28
+ ) -> Result<Array, JsValue> {
29
+ self.log
30
+ .prepare_entry_v0_plain_entry_storage_facts_and_put_with_builder(
31
+ &self.builder,
32
+ wall_time,
33
+ logical,
34
+ gid,
35
+ next,
36
+ entry_type,
37
+ meta_data,
38
+ payload_data,
39
+ )
40
+ }
41
+
42
+ #[allow(clippy::too_many_arguments)]
43
+ pub fn prepare_plain_entry_storage_facts_trim_and_put(
44
+ &mut self,
45
+ wall_time: u64,
46
+ logical: u32,
47
+ gid: String,
48
+ next: Array,
49
+ entry_type: u8,
50
+ meta_data: JsValue,
51
+ payload_data: Uint8Array,
52
+ trim_length_to: usize,
53
+ ) -> Result<Array, JsValue> {
54
+ self.log
55
+ .prepare_entry_v0_plain_entry_storage_facts_trim_and_put_with_builder(
56
+ &self.builder,
57
+ wall_time,
58
+ logical,
59
+ gid,
60
+ next,
61
+ entry_type,
62
+ meta_data,
63
+ payload_data,
64
+ trim_length_to,
65
+ )
66
+ }
67
+
68
+ #[allow(clippy::too_many_arguments)]
69
+ pub fn prepare_plain_no_next_storage_append_transaction(
70
+ &mut self,
71
+ wall_time: u64,
72
+ logical: u32,
73
+ gid: String,
74
+ entry_type: u8,
75
+ meta_data: JsValue,
76
+ payload_data: Uint8Array,
77
+ replicas: usize,
78
+ role_age_ms: f64,
79
+ now: String,
80
+ self_hash: String,
81
+ self_replicating: bool,
82
+ resolve_trimmed_entries: bool,
83
+ ) -> Result<Array, JsValue> {
84
+ self.prepare_plain_storage_append_transaction_inner(
85
+ wall_time,
86
+ logical,
87
+ gid,
88
+ Vec::new(),
89
+ entry_type,
90
+ meta_data,
91
+ payload_data,
92
+ replicas,
93
+ role_age_ms,
94
+ now,
95
+ self_hash,
96
+ self_replicating,
97
+ resolve_trimmed_entries,
98
+ None,
99
+ false,
100
+ None,
101
+ )
102
+ }
103
+
104
+ #[allow(clippy::too_many_arguments)]
105
+ pub fn prepare_plain_no_next_storage_append_transaction_trim(
106
+ &mut self,
107
+ wall_time: u64,
108
+ logical: u32,
109
+ gid: String,
110
+ entry_type: u8,
111
+ meta_data: JsValue,
112
+ payload_data: Uint8Array,
113
+ replicas: usize,
114
+ role_age_ms: f64,
115
+ now: String,
116
+ self_hash: String,
117
+ self_replicating: bool,
118
+ resolve_trimmed_entries: bool,
119
+ trim_length_to: usize,
120
+ ) -> Result<Array, JsValue> {
121
+ self.prepare_plain_storage_append_transaction_inner(
122
+ wall_time,
123
+ logical,
124
+ gid,
125
+ Vec::new(),
126
+ entry_type,
127
+ meta_data,
128
+ payload_data,
129
+ replicas,
130
+ role_age_ms,
131
+ now,
132
+ self_hash,
133
+ self_replicating,
134
+ resolve_trimmed_entries,
135
+ Some(trim_length_to),
136
+ false,
137
+ None,
138
+ )
139
+ }
140
+
141
+ #[allow(clippy::too_many_arguments)]
142
+ pub fn prepare_plain_no_next_storage_append_document_index_transaction(
143
+ &mut self,
144
+ wall_time: u64,
145
+ logical: u32,
146
+ gid: String,
147
+ entry_type: u8,
148
+ meta_data: JsValue,
149
+ payload_data: Uint8Array,
150
+ replicas: usize,
151
+ role_age_ms: f64,
152
+ now: String,
153
+ self_hash: String,
154
+ self_replicating: bool,
155
+ resolve_trimmed_entries: bool,
156
+ document_key: String,
157
+ document_value_prefix_bytes: Vec<u8>,
158
+ document_existing_created: String,
159
+ document_byte_element_index_limit: usize,
160
+ document_delete_trimmed_heads: bool,
161
+ document_projection_plan: JsValue,
162
+ document_projection_encoded_document: JsValue,
163
+ document_projection_signer: JsValue,
164
+ ) -> Result<Array, JsValue> {
165
+ self.prepare_plain_storage_append_transaction_inner(
166
+ wall_time,
167
+ logical,
168
+ gid,
169
+ Vec::new(),
170
+ entry_type,
171
+ meta_data,
172
+ payload_data,
173
+ replicas,
174
+ role_age_ms,
175
+ now,
176
+ self_hash,
177
+ self_replicating,
178
+ resolve_trimmed_entries,
179
+ None,
180
+ false,
181
+ Some(document_index_append_commit(
182
+ document_key,
183
+ document_value_prefix_bytes,
184
+ document_existing_created,
185
+ document_byte_element_index_limit,
186
+ document_delete_trimmed_heads,
187
+ document_projection_plan,
188
+ document_projection_encoded_document,
189
+ document_projection_signer,
190
+ )?),
191
+ )
192
+ }
193
+
194
+ #[allow(clippy::too_many_arguments)]
195
+ pub fn prepare_plain_no_next_storage_append_document_index_transaction_trim(
196
+ &mut self,
197
+ wall_time: u64,
198
+ logical: u32,
199
+ gid: String,
200
+ entry_type: u8,
201
+ meta_data: JsValue,
202
+ payload_data: Uint8Array,
203
+ replicas: usize,
204
+ role_age_ms: f64,
205
+ now: String,
206
+ self_hash: String,
207
+ self_replicating: bool,
208
+ resolve_trimmed_entries: bool,
209
+ document_key: String,
210
+ document_value_prefix_bytes: Vec<u8>,
211
+ document_existing_created: String,
212
+ document_byte_element_index_limit: usize,
213
+ document_delete_trimmed_heads: bool,
214
+ document_projection_plan: JsValue,
215
+ document_projection_encoded_document: JsValue,
216
+ document_projection_signer: JsValue,
217
+ trim_length_to: usize,
218
+ ) -> Result<Array, JsValue> {
219
+ self.prepare_plain_storage_append_transaction_inner(
220
+ wall_time,
221
+ logical,
222
+ gid,
223
+ Vec::new(),
224
+ entry_type,
225
+ meta_data,
226
+ payload_data,
227
+ replicas,
228
+ role_age_ms,
229
+ now,
230
+ self_hash,
231
+ self_replicating,
232
+ resolve_trimmed_entries,
233
+ Some(trim_length_to),
234
+ false,
235
+ Some(document_index_append_commit(
236
+ document_key,
237
+ document_value_prefix_bytes,
238
+ document_existing_created,
239
+ document_byte_element_index_limit,
240
+ document_delete_trimmed_heads,
241
+ document_projection_plan,
242
+ document_projection_encoded_document,
243
+ document_projection_signer,
244
+ )?),
245
+ )
246
+ }
247
+
248
+ #[allow(clippy::too_many_arguments)]
249
+ pub fn prepare_plain_storage_append_transaction(
250
+ &mut self,
251
+ wall_time: u64,
252
+ logical: u32,
253
+ gid: String,
254
+ next_hashes: Array,
255
+ entry_type: u8,
256
+ meta_data: JsValue,
257
+ payload_data: Uint8Array,
258
+ replicas: usize,
259
+ role_age_ms: f64,
260
+ now: String,
261
+ self_hash: String,
262
+ self_replicating: bool,
263
+ resolve_trimmed_entries: bool,
264
+ ) -> Result<Array, JsValue> {
265
+ self.prepare_plain_storage_append_transaction_inner(
266
+ wall_time,
267
+ logical,
268
+ gid,
269
+ strings_from_array(next_hashes)?,
270
+ entry_type,
271
+ meta_data,
272
+ payload_data,
273
+ replicas,
274
+ role_age_ms,
275
+ now,
276
+ self_hash,
277
+ self_replicating,
278
+ resolve_trimmed_entries,
279
+ None,
280
+ false,
281
+ None,
282
+ )
283
+ }
284
+
285
+ #[allow(clippy::too_many_arguments)]
286
+ pub fn prepare_plain_storage_append_transaction_trim(
287
+ &mut self,
288
+ wall_time: u64,
289
+ logical: u32,
290
+ gid: String,
291
+ next_hashes: Array,
292
+ entry_type: u8,
293
+ meta_data: JsValue,
294
+ payload_data: Uint8Array,
295
+ replicas: usize,
296
+ role_age_ms: f64,
297
+ now: String,
298
+ self_hash: String,
299
+ self_replicating: bool,
300
+ resolve_trimmed_entries: bool,
301
+ trim_length_to: usize,
302
+ ) -> Result<Array, JsValue> {
303
+ self.prepare_plain_storage_append_transaction_inner(
304
+ wall_time,
305
+ logical,
306
+ gid,
307
+ strings_from_array(next_hashes)?,
308
+ entry_type,
309
+ meta_data,
310
+ payload_data,
311
+ replicas,
312
+ role_age_ms,
313
+ now,
314
+ self_hash,
315
+ self_replicating,
316
+ resolve_trimmed_entries,
317
+ Some(trim_length_to),
318
+ false,
319
+ None,
320
+ )
321
+ }
322
+
323
+ #[allow(clippy::too_many_arguments)]
324
+ pub fn prepare_plain_storage_append_document_index_transaction(
325
+ &mut self,
326
+ wall_time: u64,
327
+ logical: u32,
328
+ gid: String,
329
+ next_hashes: Array,
330
+ entry_type: u8,
331
+ meta_data: JsValue,
332
+ payload_data: Uint8Array,
333
+ replicas: usize,
334
+ role_age_ms: f64,
335
+ now: String,
336
+ self_hash: String,
337
+ self_replicating: bool,
338
+ resolve_trimmed_entries: bool,
339
+ document_key: String,
340
+ document_value_prefix_bytes: Vec<u8>,
341
+ document_existing_created: String,
342
+ document_byte_element_index_limit: usize,
343
+ document_delete_trimmed_heads: bool,
344
+ document_projection_plan: JsValue,
345
+ document_projection_encoded_document: JsValue,
346
+ document_projection_signer: JsValue,
347
+ ) -> Result<Array, JsValue> {
348
+ self.prepare_plain_storage_append_transaction_inner(
349
+ wall_time,
350
+ logical,
351
+ gid,
352
+ strings_from_array(next_hashes)?,
353
+ entry_type,
354
+ meta_data,
355
+ payload_data,
356
+ replicas,
357
+ role_age_ms,
358
+ now,
359
+ self_hash,
360
+ self_replicating,
361
+ resolve_trimmed_entries,
362
+ None,
363
+ false,
364
+ Some(document_index_append_commit(
365
+ document_key,
366
+ document_value_prefix_bytes,
367
+ document_existing_created,
368
+ document_byte_element_index_limit,
369
+ document_delete_trimmed_heads,
370
+ document_projection_plan,
371
+ document_projection_encoded_document,
372
+ document_projection_signer,
373
+ )?),
374
+ )
375
+ }
376
+
377
+ #[allow(clippy::too_many_arguments)]
378
+ pub fn prepare_plain_storage_append_document_index_transaction_trim(
379
+ &mut self,
380
+ wall_time: u64,
381
+ logical: u32,
382
+ gid: String,
383
+ next_hashes: Array,
384
+ entry_type: u8,
385
+ meta_data: JsValue,
386
+ payload_data: Uint8Array,
387
+ replicas: usize,
388
+ role_age_ms: f64,
389
+ now: String,
390
+ self_hash: String,
391
+ self_replicating: bool,
392
+ resolve_trimmed_entries: bool,
393
+ document_key: String,
394
+ document_value_prefix_bytes: Vec<u8>,
395
+ document_existing_created: String,
396
+ document_byte_element_index_limit: usize,
397
+ document_delete_trimmed_heads: bool,
398
+ document_projection_plan: JsValue,
399
+ document_projection_encoded_document: JsValue,
400
+ document_projection_signer: JsValue,
401
+ trim_length_to: usize,
402
+ ) -> Result<Array, JsValue> {
403
+ self.prepare_plain_storage_append_transaction_inner(
404
+ wall_time,
405
+ logical,
406
+ gid,
407
+ strings_from_array(next_hashes)?,
408
+ entry_type,
409
+ meta_data,
410
+ payload_data,
411
+ replicas,
412
+ role_age_ms,
413
+ now,
414
+ self_hash,
415
+ self_replicating,
416
+ resolve_trimmed_entries,
417
+ Some(trim_length_to),
418
+ false,
419
+ Some(document_index_append_commit(
420
+ document_key,
421
+ document_value_prefix_bytes,
422
+ document_existing_created,
423
+ document_byte_element_index_limit,
424
+ document_delete_trimmed_heads,
425
+ document_projection_plan,
426
+ document_projection_encoded_document,
427
+ document_projection_signer,
428
+ )?),
429
+ )
430
+ }
431
+ }
432
+
433
+ impl NativePeerbitBackbone {
434
+ #[allow(clippy::too_many_arguments)]
435
+ pub(crate) fn prepare_plain_storage_append_transaction_inner(
436
+ &mut self,
437
+ wall_time: u64,
438
+ logical: u32,
439
+ gid: String,
440
+ next_hashes: Vec<String>,
441
+ entry_type: u8,
442
+ meta_data: JsValue,
443
+ payload_data: Uint8Array,
444
+ replicas: usize,
445
+ role_age_ms: f64,
446
+ now: String,
447
+ self_hash: String,
448
+ self_replicating: bool,
449
+ resolve_trimmed_entries: bool,
450
+ trim_length_to: Option<usize>,
451
+ commit_blocks: bool,
452
+ document_index_commit: Option<DocumentIndexAppendCommit>,
453
+ ) -> Result<Array, JsValue> {
454
+ let profile_enabled = self.append_profile_enabled;
455
+ let storage_append_started = profile_enabled.then(js_sys::Date::now);
456
+ let payload_size = payload_data.length();
457
+ let delete_trimmed_document_heads = document_index_commit
458
+ .as_ref()
459
+ .is_some_and(|commit| commit.delete_trimmed_heads);
460
+ let previous_document_context = document_index_commit
461
+ .as_ref()
462
+ .and_then(|commit| commit.previous_context.clone());
463
+ let (entry_row, trim_rows, trim_hashes, hash, digest, meta_bytes) = if commit_blocks {
464
+ let (meta_data, payload_data) =
465
+ self.copy_append_inputs_profiled(meta_data, &payload_data);
466
+ let (entry_facts, trim_hashes, entry_row, trim_rows) = self
467
+ .prepare_committed_log_append_rows_profiled(
468
+ wall_time,
469
+ logical,
470
+ gid.clone(),
471
+ next_hashes.clone(),
472
+ entry_type,
473
+ meta_data,
474
+ payload_data,
475
+ trim_length_to,
476
+ resolve_trimmed_entries,
477
+ )?;
478
+ (
479
+ entry_row,
480
+ trim_rows,
481
+ trim_hashes,
482
+ entry_facts.hash,
483
+ entry_facts.hash_digest_bytes,
484
+ entry_facts.meta_bytes,
485
+ )
486
+ } else if let Some(trim_length_to) = trim_length_to {
487
+ let next_hashes_array = strings_to_array(next_hashes.clone());
488
+ let row = self
489
+ .log
490
+ .prepare_entry_v0_plain_entry_storage_facts_trim_and_put_with_builder(
491
+ &self.builder,
492
+ wall_time,
493
+ logical,
494
+ gid.clone(),
495
+ next_hashes_array,
496
+ entry_type,
497
+ meta_data,
498
+ payload_data,
499
+ trim_length_to,
500
+ )?;
501
+ let row = array_from_value(row.into(), "native storage trim append row")?;
502
+ let entry_row = array_from_value(row.get(0), "native storage trim append entry row")?;
503
+ let trim_rows = array_from_value(row.get(1), "native storage trim append trim rows")?;
504
+ let trim_hashes = trim_hashes_vec(&trim_rows)?;
505
+ let hash = string_field(&entry_row, 1, "storage entry hash")?;
506
+ let digest = bytes_field(&entry_row, 5, "storage entry hash digest")?;
507
+ let meta_bytes = bytes_field(&entry_row, 4, "storage entry meta bytes")?;
508
+ (entry_row, trim_rows, trim_hashes, hash, digest, meta_bytes)
509
+ } else {
510
+ let next_hashes_array = strings_to_array(next_hashes.clone());
511
+ let row = self
512
+ .log
513
+ .prepare_entry_v0_plain_entry_storage_facts_and_put_with_builder(
514
+ &self.builder,
515
+ wall_time,
516
+ logical,
517
+ gid.clone(),
518
+ next_hashes_array,
519
+ entry_type,
520
+ meta_data,
521
+ payload_data,
522
+ )?;
523
+ let hash = string_field(&row, 1, "storage entry hash")?;
524
+ let digest = bytes_field(&row, 5, "storage entry hash digest")?;
525
+ let meta_bytes = bytes_field(&row, 4, "storage entry meta bytes")?;
526
+ (row, Array::new(), Vec::new(), hash, digest, meta_bytes)
527
+ };
528
+
529
+ let hash_number = self.hash_number_profiled(&digest)?;
530
+ let document_hash = hash.clone();
531
+ let document_gid = gid.clone();
532
+ let coordinate_plan_started = profile_enabled.then(js_sys::Date::now);
533
+ let coordinate_facts = commit_local_append_for_gid_compact_core(
534
+ &mut self.shared_log,
535
+ hash,
536
+ gid,
537
+ hash_number,
538
+ &next_hashes,
539
+ &trim_hashes,
540
+ replicas,
541
+ role_age_ms,
542
+ &now,
543
+ &self_hash,
544
+ self_replicating,
545
+ true,
546
+ true,
547
+ )?;
548
+ if let Some(started) = coordinate_plan_started {
549
+ self.append_profile.coordinate_plan_ms += js_sys::Date::now() - started;
550
+ }
551
+ let coordinate_core_started = profile_enabled.then(js_sys::Date::now);
552
+ self.commit_coordinate_core_from_compact_facts(
553
+ &coordinate_facts,
554
+ &next_hashes,
555
+ &trim_hashes,
556
+ wall_time,
557
+ meta_bytes,
558
+ );
559
+ if let Some(started) = coordinate_core_started {
560
+ self.append_profile.coordinate_core_ms += js_sys::Date::now() - started;
561
+ }
562
+ let document_trimmed_heads_processed = self.commit_append_document_index_profiled(
563
+ document_index_commit,
564
+ wall_time,
565
+ &document_hash,
566
+ &document_gid,
567
+ payload_size,
568
+ None,
569
+ delete_trimmed_document_heads,
570
+ &trim_hashes,
571
+ )?;
572
+
573
+ let result_row_started = profile_enabled.then(js_sys::Date::now);
574
+ let out = Array::new();
575
+ out.push(&entry_row);
576
+ out.push(&leader_samples_to_optional_rows(&coordinate_facts.leaders));
577
+ out.push(&JsValue::from_bool(coordinate_facts.is_leader));
578
+ out.push(&JsValue::from_bool(
579
+ coordinate_facts.assigned_to_range_boundary,
580
+ ));
581
+ out.push(&coordinate_plan_to_row(&self.resolution, &coordinate_facts));
582
+ out.push(&trim_rows);
583
+ out.push(&strings_to_array(trim_hashes));
584
+ out.push(&JsValue::from_bool(document_trimmed_heads_processed));
585
+ out.push(
586
+ &previous_document_context
587
+ .as_ref()
588
+ .map(|context| document_context_facts_to_row(context).into())
589
+ .unwrap_or(JsValue::UNDEFINED),
590
+ );
591
+ if let Some(started) = result_row_started {
592
+ self.append_profile.result_row_ms += js_sys::Date::now() - started;
593
+ }
594
+ if let Some(started) = storage_append_started {
595
+ self.append_profile.storage_append_inner_ms += js_sys::Date::now() - started;
596
+ }
597
+ Ok(out)
598
+ }
599
+ }
@@ -0,0 +1,58 @@
1
+ import type { NativePeerbitBackbone } from "./index.js";
2
+
3
+ type NativeBackboneBenchmarkHandle = {
4
+ benchmark_plain_committed_no_next_storage_append_transaction_loop: (
5
+ iterations: number,
6
+ wallTimeStart: bigint,
7
+ payloadData: Uint8Array,
8
+ replicas: number,
9
+ selfHash: string,
10
+ useDocumentIndex: boolean,
11
+ documentByteElementIndexLimit: number,
12
+ trimLengthTo: number | undefined,
13
+ ) => number[];
14
+ };
15
+
16
+ export type NativeBackboneLoopBenchmark = {
17
+ totalMs: number;
18
+ logLength: number;
19
+ blockLength: number;
20
+ coordinateLength: number;
21
+ documentLength: number;
22
+ };
23
+
24
+ export const benchmarkPlainCommittedNoNextStorageAppendTransactionLoop = (
25
+ backbone: NativePeerbitBackbone,
26
+ input: {
27
+ iterations: number;
28
+ wallTimeStart: bigint | number | string;
29
+ payloadData: Uint8Array;
30
+ replicas: number;
31
+ selfHash: string;
32
+ useDocumentIndex?: boolean;
33
+ documentByteElementIndexLimit?: number;
34
+ trimLengthTo?: number;
35
+ },
36
+ ): NativeBackboneLoopBenchmark => {
37
+ const native = (
38
+ backbone as unknown as { native: NativeBackboneBenchmarkHandle }
39
+ ).native;
40
+ const row =
41
+ native.benchmark_plain_committed_no_next_storage_append_transaction_loop(
42
+ input.iterations,
43
+ BigInt(input.wallTimeStart),
44
+ input.payloadData,
45
+ input.replicas,
46
+ input.selfHash,
47
+ input.useDocumentIndex === true,
48
+ input.documentByteElementIndexLimit ?? 0,
49
+ input.trimLengthTo,
50
+ );
51
+ return {
52
+ totalMs: Number(row[0] ?? 0),
53
+ logLength: Number(row[1] ?? 0),
54
+ blockLength: Number(row[2] ?? 0),
55
+ coordinateLength: Number(row[3] ?? 0),
56
+ documentLength: Number(row[4] ?? 0),
57
+ };
58
+ };