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