1use candid::CandidType;
11use canic_cdk::utils::time::now_millis;
12use serde::Deserialize;
13use std::{cell::RefCell, collections::BTreeMap};
14
15#[derive(Clone, Debug)]
16pub(crate) struct EventState {
17 pub(crate) ops: EventOps,
18 pub(crate) perf: EventPerf,
19 pub(crate) entities: BTreeMap<String, EntityCounters>,
20 pub(crate) window_start_ms: u64,
21}
22
23impl Default for EventState {
24 fn default() -> Self {
25 Self {
26 ops: EventOps::default(),
27 perf: EventPerf::default(),
28 entities: BTreeMap::new(),
29 window_start_ms: now_millis(),
30 }
31 }
32}
33
34#[derive(Clone, Copy, Debug, Eq, PartialEq)]
42pub struct MetricRatio {
43 numerator: u64,
44 denominator: u64,
45}
46
47impl MetricRatio {
48 #[must_use]
50 pub const fn numerator(&self) -> u64 {
51 self.numerator
52 }
53
54 #[must_use]
56 pub const fn denominator(&self) -> u64 {
57 self.denominator
58 }
59
60 #[must_use]
62 pub const fn into_parts(self) -> (u64, u64) {
63 (self.numerator, self.denominator)
64 }
65}
66
67const fn ratio(numerator: u64, denominator: u64) -> Option<MetricRatio> {
71 if denominator == 0 {
72 return None;
73 }
74
75 Some(MetricRatio {
76 numerator,
77 denominator,
78 })
79}
80
81#[cfg_attr(doc, doc = "EventOps\n\nOperation counters.")]
82#[derive(CandidType, Clone, Debug, Default, Deserialize)]
83pub struct EventOps {
84 pub(crate) load_calls: u64,
86 pub(crate) save_calls: u64,
87 pub(crate) delete_calls: u64,
88 pub(crate) save_insert_calls: u64,
89 pub(crate) save_update_calls: u64,
90 pub(crate) save_replace_calls: u64,
91 pub(crate) exec_success: u64,
92 pub(crate) exec_error_corruption: u64,
93 pub(crate) exec_error_incompatible_persisted_format: u64,
94 pub(crate) exec_error_not_found: u64,
95 pub(crate) exec_error_internal: u64,
96 pub(crate) exec_error_conflict: u64,
97 pub(crate) exec_error_unsupported: u64,
98 pub(crate) exec_error_invariant_violation: u64,
99 pub(crate) exec_aborted: u64,
100 pub(crate) cache_shared_query_plan_hits: u64,
101 pub(crate) cache_shared_query_plan_misses: u64,
102 pub(crate) cache_shared_query_plan_inserts: u64,
103 pub(crate) cache_shared_query_plan_entries: u64,
104 pub(crate) cache_shared_query_plan_miss_cold: u64,
105 pub(crate) cache_shared_query_plan_miss_distinct_key: u64,
106 pub(crate) cache_shared_query_plan_miss_method_version: u64,
107 pub(crate) cache_shared_query_plan_miss_schema_fingerprint: u64,
108 pub(crate) cache_shared_query_plan_miss_visibility: u64,
109 pub(crate) cache_sql_compiled_command_hits: u64,
110 pub(crate) cache_sql_compiled_command_misses: u64,
111 pub(crate) cache_sql_compiled_command_inserts: u64,
112 pub(crate) cache_sql_compiled_command_entries: u64,
113 pub(crate) cache_sql_compiled_command_miss_cold: u64,
114 pub(crate) cache_sql_compiled_command_miss_distinct_key: u64,
115 pub(crate) cache_sql_compiled_command_miss_method_version: u64,
116 pub(crate) cache_sql_compiled_command_miss_schema_fingerprint: u64,
117 pub(crate) cache_sql_compiled_command_miss_surface: u64,
118 pub(crate) schema_reconcile_checks: u64,
119 pub(crate) schema_reconcile_exact_match: u64,
120 pub(crate) schema_reconcile_first_create: u64,
121 pub(crate) schema_reconcile_latest_snapshot_corrupt: u64,
122 pub(crate) schema_reconcile_rejected_field_slot: u64,
123 pub(crate) schema_reconcile_rejected_other: u64,
124 pub(crate) schema_reconcile_rejected_row_layout: u64,
125 pub(crate) schema_reconcile_rejected_schema_version: u64,
126 pub(crate) schema_reconcile_store_write_error: u64,
127 pub(crate) schema_store_snapshots: u64,
128 pub(crate) schema_store_encoded_bytes: u64,
129 pub(crate) schema_store_latest_snapshot_bytes: u64,
130 pub(crate) sql_compile_rejects: u64,
131 pub(crate) sql_compile_reject_cache_key: u64,
132 pub(crate) sql_compile_reject_parse: u64,
133 pub(crate) sql_compile_reject_semantic: u64,
134
135 pub(crate) plan_index: u64,
137 pub(crate) plan_keys: u64,
138 pub(crate) plan_range: u64,
139 pub(crate) plan_full_scan: u64,
140 pub(crate) plan_by_key: u64,
141 pub(crate) plan_by_keys: u64,
142 pub(crate) plan_key_range: u64,
143 pub(crate) plan_index_prefix: u64,
144 pub(crate) plan_index_multi_lookup: u64,
145 pub(crate) plan_index_range: u64,
146 pub(crate) plan_explicit_full_scan: u64,
147 pub(crate) plan_union: u64,
148 pub(crate) plan_intersection: u64,
149 pub(crate) plan_grouped_hash_materialized: u64,
150 pub(crate) plan_grouped_ordered_materialized: u64,
151 pub(crate) plan_choice_conflicting_primary_key_children_access_preferred: u64,
152 pub(crate) plan_choice_constant_false_predicate: u64,
153 pub(crate) plan_choice_empty_child_access_preferred: u64,
154 pub(crate) plan_choice_full_scan_access: u64,
155 pub(crate) plan_choice_intent_key_access_override: u64,
156 pub(crate) plan_choice_limit_zero_window: u64,
157 pub(crate) plan_choice_non_index_access: u64,
158 pub(crate) plan_choice_planner_composite_non_index: u64,
159 pub(crate) plan_choice_planner_full_scan_fallback: u64,
160 pub(crate) plan_choice_planner_key_set_access: u64,
161 pub(crate) plan_choice_planner_primary_key_lookup: u64,
162 pub(crate) plan_choice_planner_primary_key_range: u64,
163 pub(crate) plan_choice_required_order_primary_key_range_preferred: u64,
164 pub(crate) plan_choice_singleton_primary_key_child_access_preferred: u64,
165 pub(crate) prepared_shape_already_finalized: u64,
166 pub(crate) prepared_shape_generated_fallback: u64,
167
168 pub(crate) rows_loaded: u64,
170 pub(crate) rows_saved: u64,
171 pub(crate) rows_inserted: u64,
172 pub(crate) rows_updated: u64,
173 pub(crate) rows_replaced: u64,
174 pub(crate) rows_scanned: u64,
175 pub(crate) rows_filtered: u64,
176 pub(crate) rows_aggregated: u64,
177 pub(crate) rows_emitted: u64,
178 pub(crate) load_candidate_rows_scanned: u64,
179 pub(crate) load_candidate_rows_filtered: u64,
180 pub(crate) load_result_rows_emitted: u64,
181 pub(crate) rows_deleted: u64,
182 pub(crate) sql_insert_calls: u64,
183 pub(crate) sql_insert_select_calls: u64,
184 pub(crate) sql_update_calls: u64,
185 pub(crate) sql_delete_calls: u64,
186 pub(crate) sql_write_matched_rows: u64,
187 pub(crate) sql_write_mutated_rows: u64,
188 pub(crate) sql_write_returning_rows: u64,
189 pub(crate) sql_write_error_insert: u64,
190 pub(crate) sql_write_error_insert_select: u64,
191 pub(crate) sql_write_error_update: u64,
192 pub(crate) sql_write_error_delete: u64,
193 pub(crate) sql_write_error_corruption: u64,
194 pub(crate) sql_write_error_incompatible_persisted_format: u64,
195 pub(crate) sql_write_error_not_found: u64,
196 pub(crate) sql_write_error_internal: u64,
197 pub(crate) sql_write_error_conflict: u64,
198 pub(crate) sql_write_error_unsupported: u64,
199 pub(crate) sql_write_error_invariant_violation: u64,
200
201 pub(crate) index_inserts: u64,
203 pub(crate) index_removes: u64,
204 pub(crate) reverse_index_inserts: u64,
205 pub(crate) reverse_index_removes: u64,
206 pub(crate) relation_reverse_lookups: u64,
207 pub(crate) relation_delete_blocks: u64,
208 pub(crate) write_rows_touched: u64,
209 pub(crate) write_index_entries_changed: u64,
210 pub(crate) write_reverse_index_entries_changed: u64,
211 pub(crate) write_relation_checks: u64,
212 pub(crate) unique_violations: u64,
213 pub(crate) non_atomic_partial_commits: u64,
214 pub(crate) non_atomic_partial_rows_committed: u64,
215}
216
217impl EventOps {
218 #[must_use]
219 pub const fn load_calls(&self) -> u64 {
220 self.load_calls
221 }
222
223 #[must_use]
224 pub const fn save_calls(&self) -> u64 {
225 self.save_calls
226 }
227
228 #[must_use]
229 pub const fn delete_calls(&self) -> u64 {
230 self.delete_calls
231 }
232
233 #[must_use]
234 pub const fn save_insert_calls(&self) -> u64 {
235 self.save_insert_calls
236 }
237
238 #[must_use]
239 pub const fn save_update_calls(&self) -> u64 {
240 self.save_update_calls
241 }
242
243 #[must_use]
244 pub const fn save_replace_calls(&self) -> u64 {
245 self.save_replace_calls
246 }
247
248 #[must_use]
249 pub const fn exec_success(&self) -> u64 {
250 self.exec_success
251 }
252
253 #[must_use]
254 pub const fn exec_error_corruption(&self) -> u64 {
255 self.exec_error_corruption
256 }
257
258 #[must_use]
259 pub const fn exec_error_incompatible_persisted_format(&self) -> u64 {
260 self.exec_error_incompatible_persisted_format
261 }
262
263 #[must_use]
264 pub const fn exec_error_not_found(&self) -> u64 {
265 self.exec_error_not_found
266 }
267
268 #[must_use]
269 pub const fn exec_error_internal(&self) -> u64 {
270 self.exec_error_internal
271 }
272
273 #[must_use]
274 pub const fn exec_error_conflict(&self) -> u64 {
275 self.exec_error_conflict
276 }
277
278 #[must_use]
279 pub const fn exec_error_unsupported(&self) -> u64 {
280 self.exec_error_unsupported
281 }
282
283 #[must_use]
284 pub const fn exec_error_invariant_violation(&self) -> u64 {
285 self.exec_error_invariant_violation
286 }
287
288 #[must_use]
289 pub const fn exec_aborted(&self) -> u64 {
290 self.exec_aborted
291 }
292
293 #[must_use]
294 pub const fn cache_shared_query_plan_hits(&self) -> u64 {
295 self.cache_shared_query_plan_hits
296 }
297
298 #[must_use]
299 pub const fn cache_shared_query_plan_misses(&self) -> u64 {
300 self.cache_shared_query_plan_misses
301 }
302
303 #[must_use]
304 pub const fn cache_shared_query_plan_inserts(&self) -> u64 {
305 self.cache_shared_query_plan_inserts
306 }
307
308 #[must_use]
309 pub const fn cache_shared_query_plan_entries(&self) -> u64 {
310 self.cache_shared_query_plan_entries
311 }
312
313 #[must_use]
314 pub const fn cache_shared_query_plan_miss_cold(&self) -> u64 {
315 self.cache_shared_query_plan_miss_cold
316 }
317
318 #[must_use]
319 pub const fn cache_shared_query_plan_miss_distinct_key(&self) -> u64 {
320 self.cache_shared_query_plan_miss_distinct_key
321 }
322
323 #[must_use]
324 pub const fn cache_shared_query_plan_miss_method_version(&self) -> u64 {
325 self.cache_shared_query_plan_miss_method_version
326 }
327
328 #[must_use]
329 pub const fn cache_shared_query_plan_miss_schema_fingerprint(&self) -> u64 {
330 self.cache_shared_query_plan_miss_schema_fingerprint
331 }
332
333 #[must_use]
334 pub const fn cache_shared_query_plan_miss_visibility(&self) -> u64 {
335 self.cache_shared_query_plan_miss_visibility
336 }
337
338 #[must_use]
339 pub const fn cache_sql_compiled_command_hits(&self) -> u64 {
340 self.cache_sql_compiled_command_hits
341 }
342
343 #[must_use]
344 pub const fn cache_sql_compiled_command_misses(&self) -> u64 {
345 self.cache_sql_compiled_command_misses
346 }
347
348 #[must_use]
349 pub const fn cache_sql_compiled_command_inserts(&self) -> u64 {
350 self.cache_sql_compiled_command_inserts
351 }
352
353 #[must_use]
354 pub const fn cache_sql_compiled_command_entries(&self) -> u64 {
355 self.cache_sql_compiled_command_entries
356 }
357
358 #[must_use]
359 pub const fn cache_sql_compiled_command_miss_cold(&self) -> u64 {
360 self.cache_sql_compiled_command_miss_cold
361 }
362
363 #[must_use]
364 pub const fn cache_sql_compiled_command_miss_distinct_key(&self) -> u64 {
365 self.cache_sql_compiled_command_miss_distinct_key
366 }
367
368 #[must_use]
369 pub const fn cache_sql_compiled_command_miss_method_version(&self) -> u64 {
370 self.cache_sql_compiled_command_miss_method_version
371 }
372
373 #[must_use]
374 pub const fn cache_sql_compiled_command_miss_schema_fingerprint(&self) -> u64 {
375 self.cache_sql_compiled_command_miss_schema_fingerprint
376 }
377
378 #[must_use]
379 pub const fn cache_sql_compiled_command_miss_surface(&self) -> u64 {
380 self.cache_sql_compiled_command_miss_surface
381 }
382
383 #[must_use]
384 pub const fn schema_reconcile_checks(&self) -> u64 {
385 self.schema_reconcile_checks
386 }
387
388 #[must_use]
389 pub const fn schema_reconcile_exact_match(&self) -> u64 {
390 self.schema_reconcile_exact_match
391 }
392
393 #[must_use]
394 pub const fn schema_reconcile_first_create(&self) -> u64 {
395 self.schema_reconcile_first_create
396 }
397
398 #[must_use]
399 pub const fn schema_reconcile_latest_snapshot_corrupt(&self) -> u64 {
400 self.schema_reconcile_latest_snapshot_corrupt
401 }
402
403 #[must_use]
404 pub const fn schema_reconcile_rejected_field_slot(&self) -> u64 {
405 self.schema_reconcile_rejected_field_slot
406 }
407
408 #[must_use]
409 pub const fn schema_reconcile_rejected_other(&self) -> u64 {
410 self.schema_reconcile_rejected_other
411 }
412
413 #[must_use]
414 pub const fn schema_reconcile_rejected_row_layout(&self) -> u64 {
415 self.schema_reconcile_rejected_row_layout
416 }
417
418 #[must_use]
419 pub const fn schema_reconcile_rejected_schema_version(&self) -> u64 {
420 self.schema_reconcile_rejected_schema_version
421 }
422
423 #[must_use]
424 pub const fn schema_reconcile_store_write_error(&self) -> u64 {
425 self.schema_reconcile_store_write_error
426 }
427
428 #[must_use]
429 pub const fn schema_store_snapshots(&self) -> u64 {
430 self.schema_store_snapshots
431 }
432
433 #[must_use]
434 pub const fn schema_store_encoded_bytes(&self) -> u64 {
435 self.schema_store_encoded_bytes
436 }
437
438 #[must_use]
439 pub const fn schema_store_latest_snapshot_bytes(&self) -> u64 {
440 self.schema_store_latest_snapshot_bytes
441 }
442
443 #[must_use]
444 pub const fn sql_compile_rejects(&self) -> u64 {
445 self.sql_compile_rejects
446 }
447
448 #[must_use]
449 pub const fn sql_compile_reject_cache_key(&self) -> u64 {
450 self.sql_compile_reject_cache_key
451 }
452
453 #[must_use]
454 pub const fn sql_compile_reject_parse(&self) -> u64 {
455 self.sql_compile_reject_parse
456 }
457
458 #[must_use]
459 pub const fn sql_compile_reject_semantic(&self) -> u64 {
460 self.sql_compile_reject_semantic
461 }
462
463 #[must_use]
464 pub const fn plan_index(&self) -> u64 {
465 self.plan_index
466 }
467
468 #[must_use]
469 pub const fn plan_keys(&self) -> u64 {
470 self.plan_keys
471 }
472
473 #[must_use]
474 pub const fn plan_range(&self) -> u64 {
475 self.plan_range
476 }
477
478 #[must_use]
479 pub const fn plan_full_scan(&self) -> u64 {
480 self.plan_full_scan
481 }
482
483 #[must_use]
484 pub const fn plan_by_key(&self) -> u64 {
485 self.plan_by_key
486 }
487
488 #[must_use]
489 pub const fn plan_by_keys(&self) -> u64 {
490 self.plan_by_keys
491 }
492
493 #[must_use]
494 pub const fn plan_key_range(&self) -> u64 {
495 self.plan_key_range
496 }
497
498 #[must_use]
499 pub const fn plan_index_prefix(&self) -> u64 {
500 self.plan_index_prefix
501 }
502
503 #[must_use]
504 pub const fn plan_index_multi_lookup(&self) -> u64 {
505 self.plan_index_multi_lookup
506 }
507
508 #[must_use]
509 pub const fn plan_index_range(&self) -> u64 {
510 self.plan_index_range
511 }
512
513 #[must_use]
514 pub const fn plan_explicit_full_scan(&self) -> u64 {
515 self.plan_explicit_full_scan
516 }
517
518 #[must_use]
519 pub const fn plan_union(&self) -> u64 {
520 self.plan_union
521 }
522
523 #[must_use]
524 pub const fn plan_intersection(&self) -> u64 {
525 self.plan_intersection
526 }
527
528 #[must_use]
529 pub const fn plan_grouped_hash_materialized(&self) -> u64 {
530 self.plan_grouped_hash_materialized
531 }
532
533 #[must_use]
534 pub const fn plan_grouped_ordered_materialized(&self) -> u64 {
535 self.plan_grouped_ordered_materialized
536 }
537
538 #[must_use]
539 pub const fn plan_choice_conflicting_primary_key_children_access_preferred(&self) -> u64 {
540 self.plan_choice_conflicting_primary_key_children_access_preferred
541 }
542
543 #[must_use]
544 pub const fn plan_choice_constant_false_predicate(&self) -> u64 {
545 self.plan_choice_constant_false_predicate
546 }
547
548 #[must_use]
549 pub const fn plan_choice_empty_child_access_preferred(&self) -> u64 {
550 self.plan_choice_empty_child_access_preferred
551 }
552
553 #[must_use]
554 pub const fn plan_choice_full_scan_access(&self) -> u64 {
555 self.plan_choice_full_scan_access
556 }
557
558 #[must_use]
559 pub const fn plan_choice_intent_key_access_override(&self) -> u64 {
560 self.plan_choice_intent_key_access_override
561 }
562
563 #[must_use]
564 pub const fn plan_choice_limit_zero_window(&self) -> u64 {
565 self.plan_choice_limit_zero_window
566 }
567
568 #[must_use]
569 pub const fn plan_choice_non_index_access(&self) -> u64 {
570 self.plan_choice_non_index_access
571 }
572
573 #[must_use]
574 pub const fn plan_choice_planner_composite_non_index(&self) -> u64 {
575 self.plan_choice_planner_composite_non_index
576 }
577
578 #[must_use]
579 pub const fn plan_choice_planner_full_scan_fallback(&self) -> u64 {
580 self.plan_choice_planner_full_scan_fallback
581 }
582
583 #[must_use]
584 pub const fn plan_choice_planner_key_set_access(&self) -> u64 {
585 self.plan_choice_planner_key_set_access
586 }
587
588 #[must_use]
589 pub const fn plan_choice_planner_primary_key_lookup(&self) -> u64 {
590 self.plan_choice_planner_primary_key_lookup
591 }
592
593 #[must_use]
594 pub const fn plan_choice_planner_primary_key_range(&self) -> u64 {
595 self.plan_choice_planner_primary_key_range
596 }
597
598 #[must_use]
599 pub const fn plan_choice_required_order_primary_key_range_preferred(&self) -> u64 {
600 self.plan_choice_required_order_primary_key_range_preferred
601 }
602
603 #[must_use]
604 pub const fn plan_choice_singleton_primary_key_child_access_preferred(&self) -> u64 {
605 self.plan_choice_singleton_primary_key_child_access_preferred
606 }
607
608 #[must_use]
609 pub const fn prepared_shape_already_finalized(&self) -> u64 {
610 self.prepared_shape_already_finalized
611 }
612
613 #[must_use]
614 pub const fn prepared_shape_generated_fallback(&self) -> u64 {
615 self.prepared_shape_generated_fallback
616 }
617
618 #[must_use]
619 pub const fn rows_loaded(&self) -> u64 {
620 self.rows_loaded
621 }
622
623 #[must_use]
624 pub const fn rows_saved(&self) -> u64 {
625 self.rows_saved
626 }
627
628 #[must_use]
629 pub const fn rows_inserted(&self) -> u64 {
630 self.rows_inserted
631 }
632
633 #[must_use]
634 pub const fn rows_updated(&self) -> u64 {
635 self.rows_updated
636 }
637
638 #[must_use]
639 pub const fn rows_replaced(&self) -> u64 {
640 self.rows_replaced
641 }
642
643 #[must_use]
644 pub const fn rows_scanned(&self) -> u64 {
645 self.rows_scanned
646 }
647
648 #[must_use]
649 pub const fn rows_filtered(&self) -> u64 {
650 self.rows_filtered
651 }
652
653 #[must_use]
654 pub const fn rows_aggregated(&self) -> u64 {
655 self.rows_aggregated
656 }
657
658 #[must_use]
659 pub const fn rows_emitted(&self) -> u64 {
660 self.rows_emitted
661 }
662
663 #[must_use]
664 pub const fn load_candidate_rows_scanned(&self) -> u64 {
665 self.load_candidate_rows_scanned
666 }
667
668 #[must_use]
669 pub const fn load_candidate_rows_filtered(&self) -> u64 {
670 self.load_candidate_rows_filtered
671 }
672
673 #[must_use]
674 pub const fn load_result_rows_emitted(&self) -> u64 {
675 self.load_result_rows_emitted
676 }
677
678 #[must_use]
679 pub const fn rows_deleted(&self) -> u64 {
680 self.rows_deleted
681 }
682
683 #[must_use]
684 pub const fn sql_insert_calls(&self) -> u64 {
685 self.sql_insert_calls
686 }
687
688 #[must_use]
689 pub const fn sql_insert_select_calls(&self) -> u64 {
690 self.sql_insert_select_calls
691 }
692
693 #[must_use]
694 pub const fn sql_update_calls(&self) -> u64 {
695 self.sql_update_calls
696 }
697
698 #[must_use]
699 pub const fn sql_delete_calls(&self) -> u64 {
700 self.sql_delete_calls
701 }
702
703 #[must_use]
704 pub const fn sql_write_matched_rows(&self) -> u64 {
705 self.sql_write_matched_rows
706 }
707
708 #[must_use]
709 pub const fn sql_write_mutated_rows(&self) -> u64 {
710 self.sql_write_mutated_rows
711 }
712
713 #[must_use]
714 pub const fn sql_write_returning_rows(&self) -> u64 {
715 self.sql_write_returning_rows
716 }
717
718 #[must_use]
719 pub const fn sql_write_error_insert(&self) -> u64 {
720 self.sql_write_error_insert
721 }
722
723 #[must_use]
724 pub const fn sql_write_error_insert_select(&self) -> u64 {
725 self.sql_write_error_insert_select
726 }
727
728 #[must_use]
729 pub const fn sql_write_error_update(&self) -> u64 {
730 self.sql_write_error_update
731 }
732
733 #[must_use]
734 pub const fn sql_write_error_delete(&self) -> u64 {
735 self.sql_write_error_delete
736 }
737
738 #[must_use]
739 pub const fn sql_write_error_corruption(&self) -> u64 {
740 self.sql_write_error_corruption
741 }
742
743 #[must_use]
744 pub const fn sql_write_error_incompatible_persisted_format(&self) -> u64 {
745 self.sql_write_error_incompatible_persisted_format
746 }
747
748 #[must_use]
749 pub const fn sql_write_error_not_found(&self) -> u64 {
750 self.sql_write_error_not_found
751 }
752
753 #[must_use]
754 pub const fn sql_write_error_internal(&self) -> u64 {
755 self.sql_write_error_internal
756 }
757
758 #[must_use]
759 pub const fn sql_write_error_conflict(&self) -> u64 {
760 self.sql_write_error_conflict
761 }
762
763 #[must_use]
764 pub const fn sql_write_error_unsupported(&self) -> u64 {
765 self.sql_write_error_unsupported
766 }
767
768 #[must_use]
769 pub const fn sql_write_error_invariant_violation(&self) -> u64 {
770 self.sql_write_error_invariant_violation
771 }
772
773 #[must_use]
774 pub const fn index_inserts(&self) -> u64 {
775 self.index_inserts
776 }
777
778 #[must_use]
779 pub const fn index_removes(&self) -> u64 {
780 self.index_removes
781 }
782
783 #[must_use]
784 pub const fn reverse_index_inserts(&self) -> u64 {
785 self.reverse_index_inserts
786 }
787
788 #[must_use]
789 pub const fn reverse_index_removes(&self) -> u64 {
790 self.reverse_index_removes
791 }
792
793 #[must_use]
794 pub const fn relation_reverse_lookups(&self) -> u64 {
795 self.relation_reverse_lookups
796 }
797
798 #[must_use]
799 pub const fn relation_delete_blocks(&self) -> u64 {
800 self.relation_delete_blocks
801 }
802
803 #[must_use]
804 pub const fn write_rows_touched(&self) -> u64 {
805 self.write_rows_touched
806 }
807
808 #[must_use]
809 pub const fn write_index_entries_changed(&self) -> u64 {
810 self.write_index_entries_changed
811 }
812
813 #[must_use]
814 pub const fn write_reverse_index_entries_changed(&self) -> u64 {
815 self.write_reverse_index_entries_changed
816 }
817
818 #[must_use]
819 pub const fn write_relation_checks(&self) -> u64 {
820 self.write_relation_checks
821 }
822
823 #[must_use]
824 pub const fn unique_violations(&self) -> u64 {
825 self.unique_violations
826 }
827
828 #[must_use]
829 pub const fn non_atomic_partial_commits(&self) -> u64 {
830 self.non_atomic_partial_commits
831 }
832
833 #[must_use]
834 pub const fn non_atomic_partial_rows_committed(&self) -> u64 {
835 self.non_atomic_partial_rows_committed
836 }
837
838 #[must_use]
840 pub const fn load_selectivity_ratio(&self) -> Option<MetricRatio> {
841 ratio(
842 self.load_result_rows_emitted,
843 self.load_candidate_rows_scanned,
844 )
845 }
846
847 #[must_use]
849 pub const fn load_filter_ratio(&self) -> Option<MetricRatio> {
850 ratio(
851 self.load_candidate_rows_filtered,
852 self.load_candidate_rows_scanned,
853 )
854 }
855
856 #[must_use]
858 pub const fn sql_write_mutation_ratio(&self) -> Option<MetricRatio> {
859 ratio(self.sql_write_mutated_rows, self.sql_write_matched_rows)
860 }
861
862 #[must_use]
864 pub const fn sql_write_returning_ratio(&self) -> Option<MetricRatio> {
865 ratio(self.sql_write_returning_rows, self.sql_write_mutated_rows)
866 }
867
868 #[must_use]
870 pub const fn write_index_entries_per_row(&self) -> Option<MetricRatio> {
871 ratio(self.write_index_entries_changed, self.write_rows_touched)
872 }
873
874 #[must_use]
876 pub const fn write_reverse_index_entries_per_row(&self) -> Option<MetricRatio> {
877 ratio(
878 self.write_reverse_index_entries_changed,
879 self.write_rows_touched,
880 )
881 }
882
883 #[must_use]
885 pub const fn write_relation_checks_per_row(&self) -> Option<MetricRatio> {
886 ratio(self.write_relation_checks, self.write_rows_touched)
887 }
888}
889
890#[derive(Clone, Debug, Default)]
891pub(crate) struct EntityCounters {
892 pub(crate) load_calls: u64,
893 pub(crate) save_calls: u64,
894 pub(crate) delete_calls: u64,
895 pub(crate) save_insert_calls: u64,
896 pub(crate) save_update_calls: u64,
897 pub(crate) save_replace_calls: u64,
898 pub(crate) exec_success: u64,
899 pub(crate) exec_error_corruption: u64,
900 pub(crate) exec_error_incompatible_persisted_format: u64,
901 pub(crate) exec_error_not_found: u64,
902 pub(crate) exec_error_internal: u64,
903 pub(crate) exec_error_conflict: u64,
904 pub(crate) exec_error_unsupported: u64,
905 pub(crate) exec_error_invariant_violation: u64,
906 pub(crate) exec_aborted: u64,
907 pub(crate) cache_shared_query_plan_hits: u64,
908 pub(crate) cache_shared_query_plan_misses: u64,
909 pub(crate) cache_shared_query_plan_inserts: u64,
910 pub(crate) cache_shared_query_plan_miss_cold: u64,
911 pub(crate) cache_shared_query_plan_miss_distinct_key: u64,
912 pub(crate) cache_shared_query_plan_miss_method_version: u64,
913 pub(crate) cache_shared_query_plan_miss_schema_fingerprint: u64,
914 pub(crate) cache_shared_query_plan_miss_visibility: u64,
915 pub(crate) cache_sql_compiled_command_hits: u64,
916 pub(crate) cache_sql_compiled_command_misses: u64,
917 pub(crate) cache_sql_compiled_command_inserts: u64,
918 pub(crate) cache_sql_compiled_command_miss_cold: u64,
919 pub(crate) cache_sql_compiled_command_miss_distinct_key: u64,
920 pub(crate) cache_sql_compiled_command_miss_method_version: u64,
921 pub(crate) cache_sql_compiled_command_miss_schema_fingerprint: u64,
922 pub(crate) cache_sql_compiled_command_miss_surface: u64,
923 pub(crate) schema_reconcile_checks: u64,
924 pub(crate) schema_reconcile_exact_match: u64,
925 pub(crate) schema_reconcile_first_create: u64,
926 pub(crate) schema_reconcile_latest_snapshot_corrupt: u64,
927 pub(crate) schema_reconcile_rejected_field_slot: u64,
928 pub(crate) schema_reconcile_rejected_other: u64,
929 pub(crate) schema_reconcile_rejected_row_layout: u64,
930 pub(crate) schema_reconcile_rejected_schema_version: u64,
931 pub(crate) schema_reconcile_store_write_error: u64,
932 pub(crate) schema_store_snapshots: u64,
933 pub(crate) schema_store_encoded_bytes: u64,
934 pub(crate) schema_store_latest_snapshot_bytes: u64,
935 pub(crate) sql_compile_rejects: u64,
936 pub(crate) sql_compile_reject_cache_key: u64,
937 pub(crate) sql_compile_reject_parse: u64,
938 pub(crate) sql_compile_reject_semantic: u64,
939 pub(crate) plan_index: u64,
940 pub(crate) plan_keys: u64,
941 pub(crate) plan_range: u64,
942 pub(crate) plan_full_scan: u64,
943 pub(crate) plan_by_key: u64,
944 pub(crate) plan_by_keys: u64,
945 pub(crate) plan_key_range: u64,
946 pub(crate) plan_index_prefix: u64,
947 pub(crate) plan_index_multi_lookup: u64,
948 pub(crate) plan_index_range: u64,
949 pub(crate) plan_explicit_full_scan: u64,
950 pub(crate) plan_union: u64,
951 pub(crate) plan_intersection: u64,
952 pub(crate) plan_grouped_hash_materialized: u64,
953 pub(crate) plan_grouped_ordered_materialized: u64,
954 pub(crate) plan_choice_conflicting_primary_key_children_access_preferred: u64,
955 pub(crate) plan_choice_constant_false_predicate: u64,
956 pub(crate) plan_choice_empty_child_access_preferred: u64,
957 pub(crate) plan_choice_full_scan_access: u64,
958 pub(crate) plan_choice_intent_key_access_override: u64,
959 pub(crate) plan_choice_limit_zero_window: u64,
960 pub(crate) plan_choice_non_index_access: u64,
961 pub(crate) plan_choice_planner_composite_non_index: u64,
962 pub(crate) plan_choice_planner_full_scan_fallback: u64,
963 pub(crate) plan_choice_planner_key_set_access: u64,
964 pub(crate) plan_choice_planner_primary_key_lookup: u64,
965 pub(crate) plan_choice_planner_primary_key_range: u64,
966 pub(crate) plan_choice_required_order_primary_key_range_preferred: u64,
967 pub(crate) plan_choice_singleton_primary_key_child_access_preferred: u64,
968 pub(crate) prepared_shape_already_finalized: u64,
969 pub(crate) prepared_shape_generated_fallback: u64,
970 pub(crate) rows_loaded: u64,
971 pub(crate) rows_saved: u64,
972 pub(crate) rows_inserted: u64,
973 pub(crate) rows_updated: u64,
974 pub(crate) rows_replaced: u64,
975 pub(crate) rows_scanned: u64,
976 pub(crate) rows_filtered: u64,
977 pub(crate) rows_aggregated: u64,
978 pub(crate) rows_emitted: u64,
979 pub(crate) load_candidate_rows_scanned: u64,
980 pub(crate) load_candidate_rows_filtered: u64,
981 pub(crate) load_result_rows_emitted: u64,
982 pub(crate) rows_deleted: u64,
983 pub(crate) sql_insert_calls: u64,
984 pub(crate) sql_insert_select_calls: u64,
985 pub(crate) sql_update_calls: u64,
986 pub(crate) sql_delete_calls: u64,
987 pub(crate) sql_write_matched_rows: u64,
988 pub(crate) sql_write_mutated_rows: u64,
989 pub(crate) sql_write_returning_rows: u64,
990 pub(crate) sql_write_error_insert: u64,
991 pub(crate) sql_write_error_insert_select: u64,
992 pub(crate) sql_write_error_update: u64,
993 pub(crate) sql_write_error_delete: u64,
994 pub(crate) sql_write_error_corruption: u64,
995 pub(crate) sql_write_error_incompatible_persisted_format: u64,
996 pub(crate) sql_write_error_not_found: u64,
997 pub(crate) sql_write_error_internal: u64,
998 pub(crate) sql_write_error_conflict: u64,
999 pub(crate) sql_write_error_unsupported: u64,
1000 pub(crate) sql_write_error_invariant_violation: u64,
1001 pub(crate) index_inserts: u64,
1002 pub(crate) index_removes: u64,
1003 pub(crate) reverse_index_inserts: u64,
1004 pub(crate) reverse_index_removes: u64,
1005 pub(crate) relation_reverse_lookups: u64,
1006 pub(crate) relation_delete_blocks: u64,
1007 pub(crate) write_rows_touched: u64,
1008 pub(crate) write_index_entries_changed: u64,
1009 pub(crate) write_reverse_index_entries_changed: u64,
1010 pub(crate) write_relation_checks: u64,
1011 pub(crate) unique_violations: u64,
1012 pub(crate) non_atomic_partial_commits: u64,
1013 pub(crate) non_atomic_partial_rows_committed: u64,
1014}
1015
1016#[cfg_attr(doc, doc = "EventPerf\n\nInstruction totals and maxima.")]
1017#[derive(CandidType, Clone, Debug, Default, Deserialize)]
1018pub struct EventPerf {
1019 pub(crate) load_inst_total: u128,
1021 pub(crate) save_inst_total: u128,
1022 pub(crate) delete_inst_total: u128,
1023
1024 pub(crate) load_inst_max: u64,
1026 pub(crate) save_inst_max: u64,
1027 pub(crate) delete_inst_max: u64,
1028}
1029
1030impl EventPerf {
1031 #[must_use]
1032 pub const fn new(
1033 load_inst_total: u128,
1034 save_inst_total: u128,
1035 delete_inst_total: u128,
1036 load_inst_max: u64,
1037 save_inst_max: u64,
1038 delete_inst_max: u64,
1039 ) -> Self {
1040 Self {
1041 load_inst_total,
1042 save_inst_total,
1043 delete_inst_total,
1044 load_inst_max,
1045 save_inst_max,
1046 delete_inst_max,
1047 }
1048 }
1049
1050 #[must_use]
1051 pub const fn load_inst_total(&self) -> u128 {
1052 self.load_inst_total
1053 }
1054
1055 #[must_use]
1056 pub const fn save_inst_total(&self) -> u128 {
1057 self.save_inst_total
1058 }
1059
1060 #[must_use]
1061 pub const fn delete_inst_total(&self) -> u128 {
1062 self.delete_inst_total
1063 }
1064
1065 #[must_use]
1066 pub const fn load_inst_max(&self) -> u64 {
1067 self.load_inst_max
1068 }
1069
1070 #[must_use]
1071 pub const fn save_inst_max(&self) -> u64 {
1072 self.save_inst_max
1073 }
1074
1075 #[must_use]
1076 pub const fn delete_inst_max(&self) -> u64 {
1077 self.delete_inst_max
1078 }
1079}
1080
1081thread_local! {
1082 static EVENT_STATE: RefCell<EventState> = RefCell::new(EventState::default());
1083}
1084
1085pub(crate) fn with_state<R>(f: impl FnOnce(&EventState) -> R) -> R {
1087 EVENT_STATE.with(|m| f(&m.borrow()))
1088}
1089
1090pub(crate) fn with_state_mut<R>(f: impl FnOnce(&mut EventState) -> R) -> R {
1092 EVENT_STATE.with(|m| f(&mut m.borrow_mut()))
1093}
1094
1095pub(super) fn reset() {
1097 with_state_mut(|m| *m = EventState::default());
1098}
1099
1100pub(crate) fn reset_all() {
1102 reset();
1103}
1104
1105pub(super) fn add_instructions(total: &mut u128, max: &mut u64, delta_inst: u64) {
1107 *total = total.saturating_add(u128::from(delta_inst));
1108 if delta_inst > *max {
1109 *max = delta_inst;
1110 }
1111}
1112
1113#[cfg_attr(doc, doc = "EventReport\n\nMetrics query payload.")]
1114#[derive(CandidType, Clone, Debug, Default, Deserialize)]
1115pub struct EventReport {
1116 counters: Option<EventCounters>,
1117 entity_counters: Vec<EntitySummary>,
1118 window_filter_matched: bool,
1119 requested_window_start_ms: Option<u64>,
1120 active_window_start_ms: u64,
1121}
1122
1123impl EventReport {
1124 #[must_use]
1125 pub(crate) const fn new(
1126 counters: Option<EventCounters>,
1127 entity_counters: Vec<EntitySummary>,
1128 window_filter_matched: bool,
1129 requested_window_start_ms: Option<u64>,
1130 active_window_start_ms: u64,
1131 ) -> Self {
1132 Self {
1133 counters,
1134 entity_counters,
1135 window_filter_matched,
1136 requested_window_start_ms,
1137 active_window_start_ms,
1138 }
1139 }
1140
1141 #[must_use]
1142 pub const fn counters(&self) -> Option<&EventCounters> {
1143 self.counters.as_ref()
1144 }
1145
1146 #[must_use]
1147 pub fn entity_counters(&self) -> &[EntitySummary] {
1148 &self.entity_counters
1149 }
1150
1151 #[must_use]
1152 pub const fn window_filter_matched(&self) -> bool {
1153 self.window_filter_matched
1154 }
1155
1156 #[must_use]
1157 pub const fn requested_window_start_ms(&self) -> Option<u64> {
1158 self.requested_window_start_ms
1159 }
1160
1161 #[must_use]
1162 pub const fn active_window_start_ms(&self) -> u64 {
1163 self.active_window_start_ms
1164 }
1165
1166 #[must_use]
1167 pub fn into_counters(self) -> Option<EventCounters> {
1168 self.counters
1169 }
1170
1171 #[must_use]
1172 pub fn into_entity_counters(self) -> Vec<EntitySummary> {
1173 self.entity_counters
1174 }
1175}
1176
1177#[derive(CandidType, Clone, Debug, Default, Deserialize)]
1186pub struct EventCounters {
1187 pub(crate) ops: EventOps,
1188 pub(crate) perf: EventPerf,
1189 pub(crate) window_start_ms: u64,
1190 pub(crate) window_end_ms: u64,
1191 pub(crate) window_duration_ms: u64,
1192}
1193
1194impl EventCounters {
1195 #[must_use]
1196 pub(crate) const fn new(
1197 ops: EventOps,
1198 perf: EventPerf,
1199 window_start_ms: u64,
1200 window_end_ms: u64,
1201 ) -> Self {
1202 Self {
1203 ops,
1204 perf,
1205 window_start_ms,
1206 window_end_ms,
1207 window_duration_ms: window_end_ms.saturating_sub(window_start_ms),
1208 }
1209 }
1210
1211 #[must_use]
1212 pub const fn ops(&self) -> &EventOps {
1213 &self.ops
1214 }
1215
1216 #[must_use]
1217 pub const fn perf(&self) -> &EventPerf {
1218 &self.perf
1219 }
1220
1221 #[must_use]
1222 pub const fn window_start_ms(&self) -> u64 {
1223 self.window_start_ms
1224 }
1225
1226 #[must_use]
1227 pub const fn window_end_ms(&self) -> u64 {
1228 self.window_end_ms
1229 }
1230
1231 #[must_use]
1232 pub const fn window_duration_ms(&self) -> u64 {
1233 self.window_duration_ms
1234 }
1235}
1236
1237#[cfg_attr(doc, doc = "EntitySummary\n\nPer-entity metrics summary.")]
1238#[derive(CandidType, Clone, Debug, Default, Deserialize)]
1239pub struct EntitySummary {
1240 path: String,
1241 load_calls: u64,
1242 save_calls: u64,
1243 delete_calls: u64,
1244 save_insert_calls: u64,
1245 save_update_calls: u64,
1246 save_replace_calls: u64,
1247 exec_success: u64,
1248 exec_error_corruption: u64,
1249 exec_error_incompatible_persisted_format: u64,
1250 exec_error_not_found: u64,
1251 exec_error_internal: u64,
1252 exec_error_conflict: u64,
1253 exec_error_unsupported: u64,
1254 exec_error_invariant_violation: u64,
1255 exec_aborted: u64,
1256 cache_shared_query_plan_hits: u64,
1257 cache_shared_query_plan_misses: u64,
1258 cache_shared_query_plan_inserts: u64,
1259 cache_shared_query_plan_miss_cold: u64,
1260 cache_shared_query_plan_miss_distinct_key: u64,
1261 cache_shared_query_plan_miss_method_version: u64,
1262 cache_shared_query_plan_miss_schema_fingerprint: u64,
1263 cache_shared_query_plan_miss_visibility: u64,
1264 cache_sql_compiled_command_hits: u64,
1265 cache_sql_compiled_command_misses: u64,
1266 cache_sql_compiled_command_inserts: u64,
1267 cache_sql_compiled_command_miss_cold: u64,
1268 cache_sql_compiled_command_miss_distinct_key: u64,
1269 cache_sql_compiled_command_miss_method_version: u64,
1270 cache_sql_compiled_command_miss_schema_fingerprint: u64,
1271 cache_sql_compiled_command_miss_surface: u64,
1272 schema_reconcile_checks: u64,
1273 schema_reconcile_exact_match: u64,
1274 schema_reconcile_first_create: u64,
1275 schema_reconcile_latest_snapshot_corrupt: u64,
1276 schema_reconcile_rejected_field_slot: u64,
1277 schema_reconcile_rejected_other: u64,
1278 schema_reconcile_rejected_row_layout: u64,
1279 schema_reconcile_rejected_schema_version: u64,
1280 schema_reconcile_store_write_error: u64,
1281 schema_store_snapshots: u64,
1282 schema_store_encoded_bytes: u64,
1283 schema_store_latest_snapshot_bytes: u64,
1284 sql_compile_rejects: u64,
1285 sql_compile_reject_cache_key: u64,
1286 sql_compile_reject_parse: u64,
1287 sql_compile_reject_semantic: u64,
1288 plan_index: u64,
1289 plan_keys: u64,
1290 plan_range: u64,
1291 plan_full_scan: u64,
1292 plan_by_key: u64,
1293 plan_by_keys: u64,
1294 plan_key_range: u64,
1295 plan_index_prefix: u64,
1296 plan_index_multi_lookup: u64,
1297 plan_index_range: u64,
1298 plan_explicit_full_scan: u64,
1299 plan_union: u64,
1300 plan_intersection: u64,
1301 plan_grouped_hash_materialized: u64,
1302 plan_grouped_ordered_materialized: u64,
1303 plan_choice_conflicting_primary_key_children_access_preferred: u64,
1304 plan_choice_constant_false_predicate: u64,
1305 plan_choice_empty_child_access_preferred: u64,
1306 plan_choice_full_scan_access: u64,
1307 plan_choice_intent_key_access_override: u64,
1308 plan_choice_limit_zero_window: u64,
1309 plan_choice_non_index_access: u64,
1310 plan_choice_planner_composite_non_index: u64,
1311 plan_choice_planner_full_scan_fallback: u64,
1312 plan_choice_planner_key_set_access: u64,
1313 plan_choice_planner_primary_key_lookup: u64,
1314 plan_choice_planner_primary_key_range: u64,
1315 plan_choice_required_order_primary_key_range_preferred: u64,
1316 plan_choice_singleton_primary_key_child_access_preferred: u64,
1317 prepared_shape_already_finalized: u64,
1318 prepared_shape_generated_fallback: u64,
1319 rows_loaded: u64,
1320 rows_saved: u64,
1321 rows_inserted: u64,
1322 rows_updated: u64,
1323 rows_replaced: u64,
1324 rows_scanned: u64,
1325 rows_filtered: u64,
1326 rows_aggregated: u64,
1327 rows_emitted: u64,
1328 load_candidate_rows_scanned: u64,
1329 load_candidate_rows_filtered: u64,
1330 load_result_rows_emitted: u64,
1331 rows_deleted: u64,
1332 sql_insert_calls: u64,
1333 sql_insert_select_calls: u64,
1334 sql_update_calls: u64,
1335 sql_delete_calls: u64,
1336 sql_write_matched_rows: u64,
1337 sql_write_mutated_rows: u64,
1338 sql_write_returning_rows: u64,
1339 sql_write_error_insert: u64,
1340 sql_write_error_insert_select: u64,
1341 sql_write_error_update: u64,
1342 sql_write_error_delete: u64,
1343 sql_write_error_corruption: u64,
1344 sql_write_error_incompatible_persisted_format: u64,
1345 sql_write_error_not_found: u64,
1346 sql_write_error_internal: u64,
1347 sql_write_error_conflict: u64,
1348 sql_write_error_unsupported: u64,
1349 sql_write_error_invariant_violation: u64,
1350 index_inserts: u64,
1351 index_removes: u64,
1352 reverse_index_inserts: u64,
1353 reverse_index_removes: u64,
1354 relation_reverse_lookups: u64,
1355 relation_delete_blocks: u64,
1356 write_rows_touched: u64,
1357 write_index_entries_changed: u64,
1358 write_reverse_index_entries_changed: u64,
1359 write_relation_checks: u64,
1360 unique_violations: u64,
1361 non_atomic_partial_commits: u64,
1362 non_atomic_partial_rows_committed: u64,
1363}
1364
1365impl EntitySummary {
1366 #[must_use]
1367 pub const fn path(&self) -> &str {
1368 self.path.as_str()
1369 }
1370
1371 #[must_use]
1372 pub const fn load_calls(&self) -> u64 {
1373 self.load_calls
1374 }
1375
1376 #[must_use]
1377 pub const fn save_calls(&self) -> u64 {
1378 self.save_calls
1379 }
1380
1381 #[must_use]
1382 pub const fn delete_calls(&self) -> u64 {
1383 self.delete_calls
1384 }
1385
1386 #[must_use]
1387 pub const fn save_insert_calls(&self) -> u64 {
1388 self.save_insert_calls
1389 }
1390
1391 #[must_use]
1392 pub const fn save_update_calls(&self) -> u64 {
1393 self.save_update_calls
1394 }
1395
1396 #[must_use]
1397 pub const fn save_replace_calls(&self) -> u64 {
1398 self.save_replace_calls
1399 }
1400
1401 #[must_use]
1402 pub const fn exec_success(&self) -> u64 {
1403 self.exec_success
1404 }
1405
1406 #[must_use]
1407 pub const fn exec_error_corruption(&self) -> u64 {
1408 self.exec_error_corruption
1409 }
1410
1411 #[must_use]
1412 pub const fn exec_error_incompatible_persisted_format(&self) -> u64 {
1413 self.exec_error_incompatible_persisted_format
1414 }
1415
1416 #[must_use]
1417 pub const fn exec_error_not_found(&self) -> u64 {
1418 self.exec_error_not_found
1419 }
1420
1421 #[must_use]
1422 pub const fn exec_error_internal(&self) -> u64 {
1423 self.exec_error_internal
1424 }
1425
1426 #[must_use]
1427 pub const fn exec_error_conflict(&self) -> u64 {
1428 self.exec_error_conflict
1429 }
1430
1431 #[must_use]
1432 pub const fn exec_error_unsupported(&self) -> u64 {
1433 self.exec_error_unsupported
1434 }
1435
1436 #[must_use]
1437 pub const fn exec_error_invariant_violation(&self) -> u64 {
1438 self.exec_error_invariant_violation
1439 }
1440
1441 #[must_use]
1442 pub const fn exec_aborted(&self) -> u64 {
1443 self.exec_aborted
1444 }
1445
1446 #[must_use]
1447 pub const fn cache_shared_query_plan_hits(&self) -> u64 {
1448 self.cache_shared_query_plan_hits
1449 }
1450
1451 #[must_use]
1452 pub const fn cache_shared_query_plan_misses(&self) -> u64 {
1453 self.cache_shared_query_plan_misses
1454 }
1455
1456 #[must_use]
1457 pub const fn cache_shared_query_plan_inserts(&self) -> u64 {
1458 self.cache_shared_query_plan_inserts
1459 }
1460
1461 #[must_use]
1462 pub const fn cache_shared_query_plan_miss_cold(&self) -> u64 {
1463 self.cache_shared_query_plan_miss_cold
1464 }
1465
1466 #[must_use]
1467 pub const fn cache_shared_query_plan_miss_distinct_key(&self) -> u64 {
1468 self.cache_shared_query_plan_miss_distinct_key
1469 }
1470
1471 #[must_use]
1472 pub const fn cache_shared_query_plan_miss_method_version(&self) -> u64 {
1473 self.cache_shared_query_plan_miss_method_version
1474 }
1475
1476 #[must_use]
1477 pub const fn cache_shared_query_plan_miss_schema_fingerprint(&self) -> u64 {
1478 self.cache_shared_query_plan_miss_schema_fingerprint
1479 }
1480
1481 #[must_use]
1482 pub const fn cache_shared_query_plan_miss_visibility(&self) -> u64 {
1483 self.cache_shared_query_plan_miss_visibility
1484 }
1485
1486 #[must_use]
1487 pub const fn cache_sql_compiled_command_hits(&self) -> u64 {
1488 self.cache_sql_compiled_command_hits
1489 }
1490
1491 #[must_use]
1492 pub const fn cache_sql_compiled_command_misses(&self) -> u64 {
1493 self.cache_sql_compiled_command_misses
1494 }
1495
1496 #[must_use]
1497 pub const fn cache_sql_compiled_command_inserts(&self) -> u64 {
1498 self.cache_sql_compiled_command_inserts
1499 }
1500
1501 #[must_use]
1502 pub const fn cache_sql_compiled_command_miss_cold(&self) -> u64 {
1503 self.cache_sql_compiled_command_miss_cold
1504 }
1505
1506 #[must_use]
1507 pub const fn cache_sql_compiled_command_miss_distinct_key(&self) -> u64 {
1508 self.cache_sql_compiled_command_miss_distinct_key
1509 }
1510
1511 #[must_use]
1512 pub const fn cache_sql_compiled_command_miss_method_version(&self) -> u64 {
1513 self.cache_sql_compiled_command_miss_method_version
1514 }
1515
1516 #[must_use]
1517 pub const fn cache_sql_compiled_command_miss_schema_fingerprint(&self) -> u64 {
1518 self.cache_sql_compiled_command_miss_schema_fingerprint
1519 }
1520
1521 #[must_use]
1522 pub const fn cache_sql_compiled_command_miss_surface(&self) -> u64 {
1523 self.cache_sql_compiled_command_miss_surface
1524 }
1525
1526 #[must_use]
1527 pub const fn schema_reconcile_checks(&self) -> u64 {
1528 self.schema_reconcile_checks
1529 }
1530
1531 #[must_use]
1532 pub const fn schema_reconcile_exact_match(&self) -> u64 {
1533 self.schema_reconcile_exact_match
1534 }
1535
1536 #[must_use]
1537 pub const fn schema_reconcile_first_create(&self) -> u64 {
1538 self.schema_reconcile_first_create
1539 }
1540
1541 #[must_use]
1542 pub const fn schema_reconcile_latest_snapshot_corrupt(&self) -> u64 {
1543 self.schema_reconcile_latest_snapshot_corrupt
1544 }
1545
1546 #[must_use]
1547 pub const fn schema_reconcile_rejected_field_slot(&self) -> u64 {
1548 self.schema_reconcile_rejected_field_slot
1549 }
1550
1551 #[must_use]
1552 pub const fn schema_reconcile_rejected_other(&self) -> u64 {
1553 self.schema_reconcile_rejected_other
1554 }
1555
1556 #[must_use]
1557 pub const fn schema_reconcile_rejected_row_layout(&self) -> u64 {
1558 self.schema_reconcile_rejected_row_layout
1559 }
1560
1561 #[must_use]
1562 pub const fn schema_reconcile_rejected_schema_version(&self) -> u64 {
1563 self.schema_reconcile_rejected_schema_version
1564 }
1565
1566 #[must_use]
1567 pub const fn schema_reconcile_store_write_error(&self) -> u64 {
1568 self.schema_reconcile_store_write_error
1569 }
1570
1571 #[must_use]
1572 pub const fn schema_store_snapshots(&self) -> u64 {
1573 self.schema_store_snapshots
1574 }
1575
1576 #[must_use]
1577 pub const fn schema_store_encoded_bytes(&self) -> u64 {
1578 self.schema_store_encoded_bytes
1579 }
1580
1581 #[must_use]
1582 pub const fn schema_store_latest_snapshot_bytes(&self) -> u64 {
1583 self.schema_store_latest_snapshot_bytes
1584 }
1585
1586 #[must_use]
1587 pub const fn sql_compile_rejects(&self) -> u64 {
1588 self.sql_compile_rejects
1589 }
1590
1591 #[must_use]
1592 pub const fn sql_compile_reject_cache_key(&self) -> u64 {
1593 self.sql_compile_reject_cache_key
1594 }
1595
1596 #[must_use]
1597 pub const fn sql_compile_reject_parse(&self) -> u64 {
1598 self.sql_compile_reject_parse
1599 }
1600
1601 #[must_use]
1602 pub const fn sql_compile_reject_semantic(&self) -> u64 {
1603 self.sql_compile_reject_semantic
1604 }
1605
1606 #[must_use]
1607 pub const fn plan_index(&self) -> u64 {
1608 self.plan_index
1609 }
1610
1611 #[must_use]
1612 pub const fn plan_keys(&self) -> u64 {
1613 self.plan_keys
1614 }
1615
1616 #[must_use]
1617 pub const fn plan_range(&self) -> u64 {
1618 self.plan_range
1619 }
1620
1621 #[must_use]
1622 pub const fn plan_full_scan(&self) -> u64 {
1623 self.plan_full_scan
1624 }
1625
1626 #[must_use]
1627 pub const fn plan_by_key(&self) -> u64 {
1628 self.plan_by_key
1629 }
1630
1631 #[must_use]
1632 pub const fn plan_by_keys(&self) -> u64 {
1633 self.plan_by_keys
1634 }
1635
1636 #[must_use]
1637 pub const fn plan_key_range(&self) -> u64 {
1638 self.plan_key_range
1639 }
1640
1641 #[must_use]
1642 pub const fn plan_index_prefix(&self) -> u64 {
1643 self.plan_index_prefix
1644 }
1645
1646 #[must_use]
1647 pub const fn plan_index_multi_lookup(&self) -> u64 {
1648 self.plan_index_multi_lookup
1649 }
1650
1651 #[must_use]
1652 pub const fn plan_index_range(&self) -> u64 {
1653 self.plan_index_range
1654 }
1655
1656 #[must_use]
1657 pub const fn plan_explicit_full_scan(&self) -> u64 {
1658 self.plan_explicit_full_scan
1659 }
1660
1661 #[must_use]
1662 pub const fn plan_union(&self) -> u64 {
1663 self.plan_union
1664 }
1665
1666 #[must_use]
1667 pub const fn plan_intersection(&self) -> u64 {
1668 self.plan_intersection
1669 }
1670
1671 #[must_use]
1672 pub const fn plan_grouped_hash_materialized(&self) -> u64 {
1673 self.plan_grouped_hash_materialized
1674 }
1675
1676 #[must_use]
1677 pub const fn plan_grouped_ordered_materialized(&self) -> u64 {
1678 self.plan_grouped_ordered_materialized
1679 }
1680
1681 #[must_use]
1682 pub const fn plan_choice_conflicting_primary_key_children_access_preferred(&self) -> u64 {
1683 self.plan_choice_conflicting_primary_key_children_access_preferred
1684 }
1685
1686 #[must_use]
1687 pub const fn plan_choice_constant_false_predicate(&self) -> u64 {
1688 self.plan_choice_constant_false_predicate
1689 }
1690
1691 #[must_use]
1692 pub const fn plan_choice_empty_child_access_preferred(&self) -> u64 {
1693 self.plan_choice_empty_child_access_preferred
1694 }
1695
1696 #[must_use]
1697 pub const fn plan_choice_full_scan_access(&self) -> u64 {
1698 self.plan_choice_full_scan_access
1699 }
1700
1701 #[must_use]
1702 pub const fn plan_choice_intent_key_access_override(&self) -> u64 {
1703 self.plan_choice_intent_key_access_override
1704 }
1705
1706 #[must_use]
1707 pub const fn plan_choice_limit_zero_window(&self) -> u64 {
1708 self.plan_choice_limit_zero_window
1709 }
1710
1711 #[must_use]
1712 pub const fn plan_choice_non_index_access(&self) -> u64 {
1713 self.plan_choice_non_index_access
1714 }
1715
1716 #[must_use]
1717 pub const fn plan_choice_planner_composite_non_index(&self) -> u64 {
1718 self.plan_choice_planner_composite_non_index
1719 }
1720
1721 #[must_use]
1722 pub const fn plan_choice_planner_full_scan_fallback(&self) -> u64 {
1723 self.plan_choice_planner_full_scan_fallback
1724 }
1725
1726 #[must_use]
1727 pub const fn plan_choice_planner_key_set_access(&self) -> u64 {
1728 self.plan_choice_planner_key_set_access
1729 }
1730
1731 #[must_use]
1732 pub const fn plan_choice_planner_primary_key_lookup(&self) -> u64 {
1733 self.plan_choice_planner_primary_key_lookup
1734 }
1735
1736 #[must_use]
1737 pub const fn plan_choice_planner_primary_key_range(&self) -> u64 {
1738 self.plan_choice_planner_primary_key_range
1739 }
1740
1741 #[must_use]
1742 pub const fn plan_choice_required_order_primary_key_range_preferred(&self) -> u64 {
1743 self.plan_choice_required_order_primary_key_range_preferred
1744 }
1745
1746 #[must_use]
1747 pub const fn plan_choice_singleton_primary_key_child_access_preferred(&self) -> u64 {
1748 self.plan_choice_singleton_primary_key_child_access_preferred
1749 }
1750
1751 #[must_use]
1752 pub const fn prepared_shape_already_finalized(&self) -> u64 {
1753 self.prepared_shape_already_finalized
1754 }
1755
1756 #[must_use]
1757 pub const fn prepared_shape_generated_fallback(&self) -> u64 {
1758 self.prepared_shape_generated_fallback
1759 }
1760
1761 #[must_use]
1762 pub const fn rows_loaded(&self) -> u64 {
1763 self.rows_loaded
1764 }
1765
1766 #[must_use]
1767 pub const fn rows_saved(&self) -> u64 {
1768 self.rows_saved
1769 }
1770
1771 #[must_use]
1772 pub const fn rows_inserted(&self) -> u64 {
1773 self.rows_inserted
1774 }
1775
1776 #[must_use]
1777 pub const fn rows_updated(&self) -> u64 {
1778 self.rows_updated
1779 }
1780
1781 #[must_use]
1782 pub const fn rows_replaced(&self) -> u64 {
1783 self.rows_replaced
1784 }
1785
1786 #[must_use]
1787 pub const fn rows_scanned(&self) -> u64 {
1788 self.rows_scanned
1789 }
1790
1791 #[must_use]
1792 pub const fn rows_filtered(&self) -> u64 {
1793 self.rows_filtered
1794 }
1795
1796 #[must_use]
1797 pub const fn rows_aggregated(&self) -> u64 {
1798 self.rows_aggregated
1799 }
1800
1801 #[must_use]
1802 pub const fn rows_emitted(&self) -> u64 {
1803 self.rows_emitted
1804 }
1805
1806 #[must_use]
1807 pub const fn load_candidate_rows_scanned(&self) -> u64 {
1808 self.load_candidate_rows_scanned
1809 }
1810
1811 #[must_use]
1812 pub const fn load_candidate_rows_filtered(&self) -> u64 {
1813 self.load_candidate_rows_filtered
1814 }
1815
1816 #[must_use]
1817 pub const fn load_result_rows_emitted(&self) -> u64 {
1818 self.load_result_rows_emitted
1819 }
1820
1821 #[must_use]
1822 pub const fn rows_deleted(&self) -> u64 {
1823 self.rows_deleted
1824 }
1825
1826 #[must_use]
1827 pub const fn sql_insert_calls(&self) -> u64 {
1828 self.sql_insert_calls
1829 }
1830
1831 #[must_use]
1832 pub const fn sql_insert_select_calls(&self) -> u64 {
1833 self.sql_insert_select_calls
1834 }
1835
1836 #[must_use]
1837 pub const fn sql_update_calls(&self) -> u64 {
1838 self.sql_update_calls
1839 }
1840
1841 #[must_use]
1842 pub const fn sql_delete_calls(&self) -> u64 {
1843 self.sql_delete_calls
1844 }
1845
1846 #[must_use]
1847 pub const fn sql_write_matched_rows(&self) -> u64 {
1848 self.sql_write_matched_rows
1849 }
1850
1851 #[must_use]
1852 pub const fn sql_write_mutated_rows(&self) -> u64 {
1853 self.sql_write_mutated_rows
1854 }
1855
1856 #[must_use]
1857 pub const fn sql_write_returning_rows(&self) -> u64 {
1858 self.sql_write_returning_rows
1859 }
1860
1861 #[must_use]
1862 pub const fn sql_write_error_insert(&self) -> u64 {
1863 self.sql_write_error_insert
1864 }
1865
1866 #[must_use]
1867 pub const fn sql_write_error_insert_select(&self) -> u64 {
1868 self.sql_write_error_insert_select
1869 }
1870
1871 #[must_use]
1872 pub const fn sql_write_error_update(&self) -> u64 {
1873 self.sql_write_error_update
1874 }
1875
1876 #[must_use]
1877 pub const fn sql_write_error_delete(&self) -> u64 {
1878 self.sql_write_error_delete
1879 }
1880
1881 #[must_use]
1882 pub const fn sql_write_error_corruption(&self) -> u64 {
1883 self.sql_write_error_corruption
1884 }
1885
1886 #[must_use]
1887 pub const fn sql_write_error_incompatible_persisted_format(&self) -> u64 {
1888 self.sql_write_error_incompatible_persisted_format
1889 }
1890
1891 #[must_use]
1892 pub const fn sql_write_error_not_found(&self) -> u64 {
1893 self.sql_write_error_not_found
1894 }
1895
1896 #[must_use]
1897 pub const fn sql_write_error_internal(&self) -> u64 {
1898 self.sql_write_error_internal
1899 }
1900
1901 #[must_use]
1902 pub const fn sql_write_error_conflict(&self) -> u64 {
1903 self.sql_write_error_conflict
1904 }
1905
1906 #[must_use]
1907 pub const fn sql_write_error_unsupported(&self) -> u64 {
1908 self.sql_write_error_unsupported
1909 }
1910
1911 #[must_use]
1912 pub const fn sql_write_error_invariant_violation(&self) -> u64 {
1913 self.sql_write_error_invariant_violation
1914 }
1915
1916 #[must_use]
1917 pub const fn index_inserts(&self) -> u64 {
1918 self.index_inserts
1919 }
1920
1921 #[must_use]
1922 pub const fn index_removes(&self) -> u64 {
1923 self.index_removes
1924 }
1925
1926 #[must_use]
1927 pub const fn reverse_index_inserts(&self) -> u64 {
1928 self.reverse_index_inserts
1929 }
1930
1931 #[must_use]
1932 pub const fn reverse_index_removes(&self) -> u64 {
1933 self.reverse_index_removes
1934 }
1935
1936 #[must_use]
1937 pub const fn relation_reverse_lookups(&self) -> u64 {
1938 self.relation_reverse_lookups
1939 }
1940
1941 #[must_use]
1942 pub const fn relation_delete_blocks(&self) -> u64 {
1943 self.relation_delete_blocks
1944 }
1945
1946 #[must_use]
1947 pub const fn write_rows_touched(&self) -> u64 {
1948 self.write_rows_touched
1949 }
1950
1951 #[must_use]
1952 pub const fn write_index_entries_changed(&self) -> u64 {
1953 self.write_index_entries_changed
1954 }
1955
1956 #[must_use]
1957 pub const fn write_reverse_index_entries_changed(&self) -> u64 {
1958 self.write_reverse_index_entries_changed
1959 }
1960
1961 #[must_use]
1962 pub const fn write_relation_checks(&self) -> u64 {
1963 self.write_relation_checks
1964 }
1965
1966 #[must_use]
1967 pub const fn unique_violations(&self) -> u64 {
1968 self.unique_violations
1969 }
1970
1971 #[must_use]
1972 pub const fn non_atomic_partial_commits(&self) -> u64 {
1973 self.non_atomic_partial_commits
1974 }
1975
1976 #[must_use]
1977 pub const fn non_atomic_partial_rows_committed(&self) -> u64 {
1978 self.non_atomic_partial_rows_committed
1979 }
1980
1981 #[must_use]
1983 pub const fn load_selectivity_ratio(&self) -> Option<MetricRatio> {
1984 ratio(
1985 self.load_result_rows_emitted,
1986 self.load_candidate_rows_scanned,
1987 )
1988 }
1989
1990 #[must_use]
1992 pub const fn load_filter_ratio(&self) -> Option<MetricRatio> {
1993 ratio(
1994 self.load_candidate_rows_filtered,
1995 self.load_candidate_rows_scanned,
1996 )
1997 }
1998
1999 #[must_use]
2001 pub const fn sql_write_mutation_ratio(&self) -> Option<MetricRatio> {
2002 ratio(self.sql_write_mutated_rows, self.sql_write_matched_rows)
2003 }
2004
2005 #[must_use]
2007 pub const fn sql_write_returning_ratio(&self) -> Option<MetricRatio> {
2008 ratio(self.sql_write_returning_rows, self.sql_write_mutated_rows)
2009 }
2010
2011 #[must_use]
2013 pub const fn write_index_entries_per_row(&self) -> Option<MetricRatio> {
2014 ratio(self.write_index_entries_changed, self.write_rows_touched)
2015 }
2016
2017 #[must_use]
2019 pub const fn write_reverse_index_entries_per_row(&self) -> Option<MetricRatio> {
2020 ratio(
2021 self.write_reverse_index_entries_changed,
2022 self.write_rows_touched,
2023 )
2024 }
2025
2026 #[must_use]
2028 pub const fn write_relation_checks_per_row(&self) -> Option<MetricRatio> {
2029 ratio(self.write_relation_checks, self.write_rows_touched)
2030 }
2031
2032 #[expect(clippy::too_many_lines)]
2035 const fn activity_score(&self) -> u64 {
2036 self.load_calls
2037 .saturating_add(self.save_calls)
2038 .saturating_add(self.delete_calls)
2039 .saturating_add(self.save_insert_calls)
2040 .saturating_add(self.save_update_calls)
2041 .saturating_add(self.save_replace_calls)
2042 .saturating_add(self.exec_success)
2043 .saturating_add(self.exec_error_corruption)
2044 .saturating_add(self.exec_error_incompatible_persisted_format)
2045 .saturating_add(self.exec_error_not_found)
2046 .saturating_add(self.exec_error_internal)
2047 .saturating_add(self.exec_error_conflict)
2048 .saturating_add(self.exec_error_unsupported)
2049 .saturating_add(self.exec_error_invariant_violation)
2050 .saturating_add(self.exec_aborted)
2051 .saturating_add(self.cache_shared_query_plan_hits)
2052 .saturating_add(self.cache_shared_query_plan_misses)
2053 .saturating_add(self.cache_shared_query_plan_inserts)
2054 .saturating_add(self.cache_shared_query_plan_miss_cold)
2055 .saturating_add(self.cache_shared_query_plan_miss_distinct_key)
2056 .saturating_add(self.cache_shared_query_plan_miss_method_version)
2057 .saturating_add(self.cache_shared_query_plan_miss_schema_fingerprint)
2058 .saturating_add(self.cache_shared_query_plan_miss_visibility)
2059 .saturating_add(self.cache_sql_compiled_command_hits)
2060 .saturating_add(self.cache_sql_compiled_command_misses)
2061 .saturating_add(self.cache_sql_compiled_command_inserts)
2062 .saturating_add(self.cache_sql_compiled_command_miss_cold)
2063 .saturating_add(self.cache_sql_compiled_command_miss_distinct_key)
2064 .saturating_add(self.cache_sql_compiled_command_miss_method_version)
2065 .saturating_add(self.cache_sql_compiled_command_miss_schema_fingerprint)
2066 .saturating_add(self.cache_sql_compiled_command_miss_surface)
2067 .saturating_add(self.schema_reconcile_checks)
2068 .saturating_add(self.schema_reconcile_exact_match)
2069 .saturating_add(self.schema_reconcile_first_create)
2070 .saturating_add(self.schema_reconcile_latest_snapshot_corrupt)
2071 .saturating_add(self.schema_reconcile_rejected_field_slot)
2072 .saturating_add(self.schema_reconcile_rejected_other)
2073 .saturating_add(self.schema_reconcile_rejected_row_layout)
2074 .saturating_add(self.schema_reconcile_rejected_schema_version)
2075 .saturating_add(self.schema_reconcile_store_write_error)
2076 .saturating_add(self.schema_store_snapshots)
2077 .saturating_add(self.schema_store_encoded_bytes)
2078 .saturating_add(self.schema_store_latest_snapshot_bytes)
2079 .saturating_add(self.sql_compile_rejects)
2080 .saturating_add(self.sql_compile_reject_cache_key)
2081 .saturating_add(self.sql_compile_reject_parse)
2082 .saturating_add(self.sql_compile_reject_semantic)
2083 .saturating_add(self.plan_index)
2084 .saturating_add(self.plan_keys)
2085 .saturating_add(self.plan_range)
2086 .saturating_add(self.plan_full_scan)
2087 .saturating_add(self.plan_by_key)
2088 .saturating_add(self.plan_by_keys)
2089 .saturating_add(self.plan_key_range)
2090 .saturating_add(self.plan_index_prefix)
2091 .saturating_add(self.plan_index_multi_lookup)
2092 .saturating_add(self.plan_index_range)
2093 .saturating_add(self.plan_explicit_full_scan)
2094 .saturating_add(self.plan_union)
2095 .saturating_add(self.plan_intersection)
2096 .saturating_add(self.plan_grouped_hash_materialized)
2097 .saturating_add(self.plan_grouped_ordered_materialized)
2098 .saturating_add(self.plan_choice_conflicting_primary_key_children_access_preferred)
2099 .saturating_add(self.plan_choice_constant_false_predicate)
2100 .saturating_add(self.plan_choice_empty_child_access_preferred)
2101 .saturating_add(self.plan_choice_full_scan_access)
2102 .saturating_add(self.plan_choice_intent_key_access_override)
2103 .saturating_add(self.plan_choice_limit_zero_window)
2104 .saturating_add(self.plan_choice_non_index_access)
2105 .saturating_add(self.plan_choice_planner_composite_non_index)
2106 .saturating_add(self.plan_choice_planner_full_scan_fallback)
2107 .saturating_add(self.plan_choice_planner_key_set_access)
2108 .saturating_add(self.plan_choice_planner_primary_key_lookup)
2109 .saturating_add(self.plan_choice_planner_primary_key_range)
2110 .saturating_add(self.plan_choice_required_order_primary_key_range_preferred)
2111 .saturating_add(self.plan_choice_singleton_primary_key_child_access_preferred)
2112 .saturating_add(self.prepared_shape_already_finalized)
2113 .saturating_add(self.prepared_shape_generated_fallback)
2114 .saturating_add(self.rows_loaded)
2115 .saturating_add(self.rows_saved)
2116 .saturating_add(self.rows_inserted)
2117 .saturating_add(self.rows_updated)
2118 .saturating_add(self.rows_replaced)
2119 .saturating_add(self.rows_scanned)
2120 .saturating_add(self.rows_filtered)
2121 .saturating_add(self.rows_aggregated)
2122 .saturating_add(self.rows_emitted)
2123 .saturating_add(self.load_candidate_rows_scanned)
2124 .saturating_add(self.load_candidate_rows_filtered)
2125 .saturating_add(self.load_result_rows_emitted)
2126 .saturating_add(self.rows_deleted)
2127 .saturating_add(self.sql_insert_calls)
2128 .saturating_add(self.sql_insert_select_calls)
2129 .saturating_add(self.sql_update_calls)
2130 .saturating_add(self.sql_delete_calls)
2131 .saturating_add(self.sql_write_matched_rows)
2132 .saturating_add(self.sql_write_mutated_rows)
2133 .saturating_add(self.sql_write_returning_rows)
2134 .saturating_add(self.sql_write_error_insert)
2135 .saturating_add(self.sql_write_error_insert_select)
2136 .saturating_add(self.sql_write_error_update)
2137 .saturating_add(self.sql_write_error_delete)
2138 .saturating_add(self.sql_write_error_corruption)
2139 .saturating_add(self.sql_write_error_incompatible_persisted_format)
2140 .saturating_add(self.sql_write_error_not_found)
2141 .saturating_add(self.sql_write_error_internal)
2142 .saturating_add(self.sql_write_error_conflict)
2143 .saturating_add(self.sql_write_error_unsupported)
2144 .saturating_add(self.sql_write_error_invariant_violation)
2145 .saturating_add(self.index_inserts)
2146 .saturating_add(self.index_removes)
2147 .saturating_add(self.reverse_index_inserts)
2148 .saturating_add(self.reverse_index_removes)
2149 .saturating_add(self.relation_reverse_lookups)
2150 .saturating_add(self.relation_delete_blocks)
2151 .saturating_add(self.write_rows_touched)
2152 .saturating_add(self.write_index_entries_changed)
2153 .saturating_add(self.write_reverse_index_entries_changed)
2154 .saturating_add(self.write_relation_checks)
2155 .saturating_add(self.unique_violations)
2156 .saturating_add(self.non_atomic_partial_commits)
2157 .saturating_add(self.non_atomic_partial_rows_committed)
2158 }
2159}
2160
2161#[expect(clippy::too_many_lines)]
2166fn entity_summary_from_counters(path: &str, ops: &EntityCounters) -> EntitySummary {
2167 EntitySummary {
2168 path: path.to_string(),
2169 load_calls: ops.load_calls,
2170 save_calls: ops.save_calls,
2171 delete_calls: ops.delete_calls,
2172 save_insert_calls: ops.save_insert_calls,
2173 save_update_calls: ops.save_update_calls,
2174 save_replace_calls: ops.save_replace_calls,
2175 exec_success: ops.exec_success,
2176 exec_error_corruption: ops.exec_error_corruption,
2177 exec_error_incompatible_persisted_format: ops.exec_error_incompatible_persisted_format,
2178 exec_error_not_found: ops.exec_error_not_found,
2179 exec_error_internal: ops.exec_error_internal,
2180 exec_error_conflict: ops.exec_error_conflict,
2181 exec_error_unsupported: ops.exec_error_unsupported,
2182 exec_error_invariant_violation: ops.exec_error_invariant_violation,
2183 exec_aborted: ops.exec_aborted,
2184 cache_shared_query_plan_hits: ops.cache_shared_query_plan_hits,
2185 cache_shared_query_plan_misses: ops.cache_shared_query_plan_misses,
2186 cache_shared_query_plan_inserts: ops.cache_shared_query_plan_inserts,
2187 cache_shared_query_plan_miss_cold: ops.cache_shared_query_plan_miss_cold,
2188 cache_shared_query_plan_miss_distinct_key: ops.cache_shared_query_plan_miss_distinct_key,
2189 cache_shared_query_plan_miss_method_version: ops
2190 .cache_shared_query_plan_miss_method_version,
2191 cache_shared_query_plan_miss_schema_fingerprint: ops
2192 .cache_shared_query_plan_miss_schema_fingerprint,
2193 cache_shared_query_plan_miss_visibility: ops.cache_shared_query_plan_miss_visibility,
2194 cache_sql_compiled_command_hits: ops.cache_sql_compiled_command_hits,
2195 cache_sql_compiled_command_misses: ops.cache_sql_compiled_command_misses,
2196 cache_sql_compiled_command_inserts: ops.cache_sql_compiled_command_inserts,
2197 cache_sql_compiled_command_miss_cold: ops.cache_sql_compiled_command_miss_cold,
2198 cache_sql_compiled_command_miss_distinct_key: ops
2199 .cache_sql_compiled_command_miss_distinct_key,
2200 cache_sql_compiled_command_miss_method_version: ops
2201 .cache_sql_compiled_command_miss_method_version,
2202 cache_sql_compiled_command_miss_schema_fingerprint: ops
2203 .cache_sql_compiled_command_miss_schema_fingerprint,
2204 cache_sql_compiled_command_miss_surface: ops.cache_sql_compiled_command_miss_surface,
2205 schema_reconcile_checks: ops.schema_reconcile_checks,
2206 schema_reconcile_exact_match: ops.schema_reconcile_exact_match,
2207 schema_reconcile_first_create: ops.schema_reconcile_first_create,
2208 schema_reconcile_latest_snapshot_corrupt: ops.schema_reconcile_latest_snapshot_corrupt,
2209 schema_reconcile_rejected_field_slot: ops.schema_reconcile_rejected_field_slot,
2210 schema_reconcile_rejected_other: ops.schema_reconcile_rejected_other,
2211 schema_reconcile_rejected_row_layout: ops.schema_reconcile_rejected_row_layout,
2212 schema_reconcile_rejected_schema_version: ops.schema_reconcile_rejected_schema_version,
2213 schema_reconcile_store_write_error: ops.schema_reconcile_store_write_error,
2214 schema_store_snapshots: ops.schema_store_snapshots,
2215 schema_store_encoded_bytes: ops.schema_store_encoded_bytes,
2216 schema_store_latest_snapshot_bytes: ops.schema_store_latest_snapshot_bytes,
2217 sql_compile_rejects: ops.sql_compile_rejects,
2218 sql_compile_reject_cache_key: ops.sql_compile_reject_cache_key,
2219 sql_compile_reject_parse: ops.sql_compile_reject_parse,
2220 sql_compile_reject_semantic: ops.sql_compile_reject_semantic,
2221 plan_index: ops.plan_index,
2222 plan_keys: ops.plan_keys,
2223 plan_range: ops.plan_range,
2224 plan_full_scan: ops.plan_full_scan,
2225 plan_by_key: ops.plan_by_key,
2226 plan_by_keys: ops.plan_by_keys,
2227 plan_key_range: ops.plan_key_range,
2228 plan_index_prefix: ops.plan_index_prefix,
2229 plan_index_multi_lookup: ops.plan_index_multi_lookup,
2230 plan_index_range: ops.plan_index_range,
2231 plan_explicit_full_scan: ops.plan_explicit_full_scan,
2232 plan_union: ops.plan_union,
2233 plan_intersection: ops.plan_intersection,
2234 plan_grouped_hash_materialized: ops.plan_grouped_hash_materialized,
2235 plan_grouped_ordered_materialized: ops.plan_grouped_ordered_materialized,
2236 plan_choice_conflicting_primary_key_children_access_preferred: ops
2237 .plan_choice_conflicting_primary_key_children_access_preferred,
2238 plan_choice_constant_false_predicate: ops.plan_choice_constant_false_predicate,
2239 plan_choice_empty_child_access_preferred: ops.plan_choice_empty_child_access_preferred,
2240 plan_choice_full_scan_access: ops.plan_choice_full_scan_access,
2241 plan_choice_intent_key_access_override: ops.plan_choice_intent_key_access_override,
2242 plan_choice_limit_zero_window: ops.plan_choice_limit_zero_window,
2243 plan_choice_non_index_access: ops.plan_choice_non_index_access,
2244 plan_choice_planner_composite_non_index: ops.plan_choice_planner_composite_non_index,
2245 plan_choice_planner_full_scan_fallback: ops.plan_choice_planner_full_scan_fallback,
2246 plan_choice_planner_key_set_access: ops.plan_choice_planner_key_set_access,
2247 plan_choice_planner_primary_key_lookup: ops.plan_choice_planner_primary_key_lookup,
2248 plan_choice_planner_primary_key_range: ops.plan_choice_planner_primary_key_range,
2249 plan_choice_required_order_primary_key_range_preferred: ops
2250 .plan_choice_required_order_primary_key_range_preferred,
2251 plan_choice_singleton_primary_key_child_access_preferred: ops
2252 .plan_choice_singleton_primary_key_child_access_preferred,
2253 prepared_shape_already_finalized: ops.prepared_shape_already_finalized,
2254 prepared_shape_generated_fallback: ops.prepared_shape_generated_fallback,
2255 rows_loaded: ops.rows_loaded,
2256 rows_saved: ops.rows_saved,
2257 rows_inserted: ops.rows_inserted,
2258 rows_updated: ops.rows_updated,
2259 rows_replaced: ops.rows_replaced,
2260 rows_scanned: ops.rows_scanned,
2261 rows_filtered: ops.rows_filtered,
2262 rows_aggregated: ops.rows_aggregated,
2263 rows_emitted: ops.rows_emitted,
2264 load_candidate_rows_scanned: ops.load_candidate_rows_scanned,
2265 load_candidate_rows_filtered: ops.load_candidate_rows_filtered,
2266 load_result_rows_emitted: ops.load_result_rows_emitted,
2267 rows_deleted: ops.rows_deleted,
2268 sql_insert_calls: ops.sql_insert_calls,
2269 sql_insert_select_calls: ops.sql_insert_select_calls,
2270 sql_update_calls: ops.sql_update_calls,
2271 sql_delete_calls: ops.sql_delete_calls,
2272 sql_write_matched_rows: ops.sql_write_matched_rows,
2273 sql_write_mutated_rows: ops.sql_write_mutated_rows,
2274 sql_write_returning_rows: ops.sql_write_returning_rows,
2275 sql_write_error_insert: ops.sql_write_error_insert,
2276 sql_write_error_insert_select: ops.sql_write_error_insert_select,
2277 sql_write_error_update: ops.sql_write_error_update,
2278 sql_write_error_delete: ops.sql_write_error_delete,
2279 sql_write_error_corruption: ops.sql_write_error_corruption,
2280 sql_write_error_incompatible_persisted_format: ops
2281 .sql_write_error_incompatible_persisted_format,
2282 sql_write_error_not_found: ops.sql_write_error_not_found,
2283 sql_write_error_internal: ops.sql_write_error_internal,
2284 sql_write_error_conflict: ops.sql_write_error_conflict,
2285 sql_write_error_unsupported: ops.sql_write_error_unsupported,
2286 sql_write_error_invariant_violation: ops.sql_write_error_invariant_violation,
2287 index_inserts: ops.index_inserts,
2288 index_removes: ops.index_removes,
2289 reverse_index_inserts: ops.reverse_index_inserts,
2290 reverse_index_removes: ops.reverse_index_removes,
2291 relation_reverse_lookups: ops.relation_reverse_lookups,
2292 relation_delete_blocks: ops.relation_delete_blocks,
2293 write_rows_touched: ops.write_rows_touched,
2294 write_index_entries_changed: ops.write_index_entries_changed,
2295 write_reverse_index_entries_changed: ops.write_reverse_index_entries_changed,
2296 write_relation_checks: ops.write_relation_checks,
2297 unique_violations: ops.unique_violations,
2298 non_atomic_partial_commits: ops.non_atomic_partial_commits,
2299 non_atomic_partial_rows_committed: ops.non_atomic_partial_rows_committed,
2300 }
2301}
2302
2303#[must_use]
2313pub(super) fn report_window_start(window_start_ms: Option<u64>) -> EventReport {
2314 let snap = with_state(Clone::clone);
2315 if let Some(requested_window_start_ms) = window_start_ms
2316 && requested_window_start_ms > snap.window_start_ms
2317 {
2318 return EventReport::new(
2319 None,
2320 Vec::new(),
2321 false,
2322 window_start_ms,
2323 snap.window_start_ms,
2324 );
2325 }
2326
2327 let mut entity_counters: Vec<EntitySummary> = Vec::new();
2328 for (path, ops) in &snap.entities {
2329 entity_counters.push(entity_summary_from_counters(path, ops));
2330 }
2331
2332 entity_counters.sort_by(|a, b| {
2333 b.activity_score()
2334 .cmp(&a.activity_score())
2335 .then_with(|| b.rows_loaded.cmp(&a.rows_loaded))
2336 .then_with(|| b.rows_saved.cmp(&a.rows_saved))
2337 .then_with(|| b.rows_scanned.cmp(&a.rows_scanned))
2338 .then_with(|| b.rows_deleted.cmp(&a.rows_deleted))
2339 .then_with(|| a.path.cmp(&b.path))
2340 });
2341
2342 EventReport::new(
2343 Some(EventCounters::new(
2344 snap.ops.clone(),
2345 snap.perf.clone(),
2346 snap.window_start_ms,
2347 now_millis(),
2348 )),
2349 entity_counters,
2350 true,
2351 window_start_ms,
2352 snap.window_start_ms,
2353 )
2354}