Skip to main content

icydb_core/metrics/state/
ops.rs

1//! Module: metrics::state::ops
2//! Responsibility: global operation metrics DTO and derived-ratio helpers.
3//! Does not own: mutable metrics state storage or report window construction.
4//! Boundary: keeps public operation counter payload shape separate from state.
5
6use candid::CandidType;
7use serde::Deserialize;
8
9///
10/// MetricRatio
11///
12/// MetricRatio carries a derived metric as an exact raw numerator and
13/// denominator pair. Callers can choose their own decimal rendering policy
14/// without losing precision inside the canister metrics layer.
15///
16#[derive(Clone, Copy, Debug, Eq, PartialEq)]
17pub struct MetricRatio {
18    numerator: u64,
19    denominator: u64,
20}
21
22impl MetricRatio {
23    /// Returns the ratio numerator.
24    #[must_use]
25    pub const fn numerator(&self) -> u64 {
26        self.numerator
27    }
28
29    /// Returns the ratio denominator.
30    #[must_use]
31    pub const fn denominator(&self) -> u64 {
32        self.denominator
33    }
34
35    /// Returns the raw numerator and denominator pair.
36    #[must_use]
37    pub const fn into_numerator_and_denominator(self) -> (u64, u64) {
38        (self.numerator, self.denominator)
39    }
40}
41
42// Convert raw counter pairs into optional ratio values without encoding a
43// sentinel for "no activity". Consumers can distinguish absent denominators
44// from legitimate zero-valued work.
45pub(in crate::metrics) const fn ratio(numerator: u64, denominator: u64) -> Option<MetricRatio> {
46    if denominator == 0 {
47        return None;
48    }
49
50    Some(MetricRatio {
51        numerator,
52        denominator,
53    })
54}
55
56#[cfg_attr(doc, doc = "EventOps\n\nOperation counters.")]
57#[derive(CandidType, Clone, Debug, Default, Deserialize)]
58pub struct EventOps {
59    // Executor entrypoints
60    pub(crate) load_calls: u64,
61    pub(crate) save_calls: u64,
62    pub(crate) delete_calls: u64,
63    pub(crate) save_insert_calls: u64,
64    pub(crate) save_update_calls: u64,
65    pub(crate) save_replace_calls: u64,
66    pub(crate) exec_success: u64,
67    pub(crate) exec_error_corruption: u64,
68    pub(crate) exec_error_incompatible_persisted_format: u64,
69    pub(crate) exec_error_not_found: u64,
70    pub(crate) exec_error_internal: u64,
71    pub(crate) exec_error_conflict: u64,
72    pub(crate) exec_error_unsupported: u64,
73    pub(crate) exec_error_invariant_violation: u64,
74    pub(crate) exec_aborted: u64,
75    pub(crate) cache_shared_query_plan_hits: u64,
76    pub(crate) cache_shared_query_plan_misses: u64,
77    pub(crate) cache_shared_query_plan_inserts: u64,
78    pub(crate) cache_shared_query_plan_entries: u64,
79    pub(crate) cache_shared_query_plan_miss_cold: u64,
80    pub(crate) cache_shared_query_plan_miss_distinct_key: u64,
81    pub(crate) cache_shared_query_plan_miss_schema_fingerprint: u64,
82    pub(crate) cache_shared_query_plan_miss_visibility: u64,
83    pub(crate) cache_sql_compiled_command_hits: u64,
84    pub(crate) cache_sql_compiled_command_misses: u64,
85    pub(crate) cache_sql_compiled_command_inserts: u64,
86    pub(crate) cache_sql_compiled_command_entries: u64,
87    pub(crate) cache_sql_compiled_command_miss_cold: u64,
88    pub(crate) cache_sql_compiled_command_miss_distinct_key: u64,
89    pub(crate) cache_sql_compiled_command_miss_schema_fingerprint: u64,
90    pub(crate) cache_sql_compiled_command_miss_surface: u64,
91    pub(crate) schema_reconcile_checks: u64,
92    pub(crate) schema_reconcile_exact_match: u64,
93    pub(crate) schema_reconcile_first_create: u64,
94    pub(crate) schema_reconcile_latest_snapshot_corrupt: u64,
95    pub(crate) schema_reconcile_rejected_field_slot: u64,
96    pub(crate) schema_reconcile_rejected_other: u64,
97    pub(crate) schema_reconcile_rejected_row_layout: u64,
98    pub(crate) schema_reconcile_rejected_schema_version: u64,
99    pub(crate) schema_reconcile_store_write_error: u64,
100    pub(crate) schema_transition_checks: u64,
101    pub(crate) schema_transition_add_expression_index: u64,
102    pub(crate) schema_transition_add_field_path_index: u64,
103    pub(crate) schema_transition_append_only_nullable_fields: u64,
104    pub(crate) schema_transition_exact_match: u64,
105    pub(crate) schema_transition_metadata_only_index_rename: u64,
106    pub(crate) schema_transition_rejected_entity_identity: u64,
107    pub(crate) schema_transition_rejected_field_contract: u64,
108    pub(crate) schema_transition_rejected_field_slot: u64,
109    pub(crate) schema_transition_rejected_row_layout: u64,
110    pub(crate) schema_transition_rejected_schema_version: u64,
111    pub(crate) schema_transition_rejected_snapshot: u64,
112    pub(crate) schema_store_snapshots: u64,
113    pub(crate) schema_store_encoded_bytes: u64,
114    pub(crate) schema_store_latest_snapshot_bytes: u64,
115    pub(crate) accepted_schema_fields: u64,
116    pub(crate) accepted_schema_nested_leaf_facts: u64,
117    pub(crate) sql_compile_rejects: u64,
118    pub(crate) sql_compile_reject_cache_key: u64,
119    pub(crate) sql_compile_reject_parse: u64,
120    pub(crate) sql_compile_reject_semantic: u64,
121
122    // Planner kinds
123    pub(crate) plan_by_key: u64,
124    pub(crate) plan_by_keys: u64,
125    pub(crate) plan_key_range: u64,
126    pub(crate) plan_index_branch_set: u64,
127    pub(crate) plan_index_prefix: u64,
128    pub(crate) plan_index_multi_lookup: u64,
129    pub(crate) plan_index_range: u64,
130    pub(crate) plan_explicit_full_scan: u64,
131    pub(crate) plan_union: u64,
132    pub(crate) plan_intersection: u64,
133    pub(crate) plan_grouped_hash_materialized: u64,
134    pub(crate) plan_grouped_ordered_materialized: u64,
135    pub(crate) plan_choice_conflicting_primary_key_children_access_preferred: u64,
136    pub(crate) plan_choice_constant_false_predicate: u64,
137    pub(crate) plan_choice_empty_child_access_preferred: u64,
138    pub(crate) plan_choice_full_scan_access: u64,
139    pub(crate) plan_choice_intent_key_access_override: u64,
140    pub(crate) plan_choice_limit_zero_window: u64,
141    pub(crate) plan_choice_non_index_access: u64,
142    pub(crate) plan_choice_planner_composite_non_index: u64,
143    pub(crate) plan_choice_planner_full_scan_fallback: u64,
144    pub(crate) plan_choice_planner_key_set_access: u64,
145    pub(crate) plan_choice_planner_primary_key_lookup: u64,
146    pub(crate) plan_choice_planner_primary_key_range: u64,
147    pub(crate) plan_choice_required_order_primary_key_range_preferred: u64,
148    pub(crate) plan_choice_singleton_primary_key_child_access_preferred: u64,
149    pub(crate) prepared_shape_already_finalized: u64,
150
151    // Rows touched
152    pub(crate) rows_loaded: u64,
153    pub(crate) rows_saved: u64,
154    pub(crate) rows_inserted: u64,
155    pub(crate) rows_updated: u64,
156    pub(crate) rows_replaced: u64,
157    pub(crate) rows_scanned: u64,
158    pub(crate) rows_filtered: u64,
159    pub(crate) rows_aggregated: u64,
160    pub(crate) rows_emitted: u64,
161    pub(crate) load_candidate_rows_scanned: u64,
162    pub(crate) load_candidate_rows_filtered: u64,
163    pub(crate) load_result_rows_emitted: u64,
164    pub(crate) rows_deleted: u64,
165    pub(crate) sql_insert_calls: u64,
166    pub(crate) sql_insert_select_calls: u64,
167    pub(crate) sql_update_calls: u64,
168    pub(crate) sql_delete_calls: u64,
169    pub(crate) sql_write_staged_rows: u64,
170    pub(crate) sql_write_matched_rows: u64,
171    pub(crate) sql_write_mutated_rows: u64,
172    pub(crate) sql_write_returning_rows: u64,
173    pub(crate) sql_write_error_insert: u64,
174    pub(crate) sql_write_error_insert_select: u64,
175    pub(crate) sql_write_error_update: u64,
176    pub(crate) sql_write_error_delete: u64,
177    pub(crate) sql_write_error_corruption: u64,
178    pub(crate) sql_write_error_incompatible_persisted_format: u64,
179    pub(crate) sql_write_error_not_found: u64,
180    pub(crate) sql_write_error_internal: u64,
181    pub(crate) sql_write_error_conflict: u64,
182    pub(crate) sql_write_error_unsupported: u64,
183    pub(crate) sql_write_error_invariant_violation: u64,
184
185    // Index maintenance
186    pub(crate) index_inserts: u64,
187    pub(crate) index_removes: u64,
188    pub(crate) reverse_index_inserts: u64,
189    pub(crate) reverse_index_removes: u64,
190    pub(crate) relation_reverse_lookups: u64,
191    pub(crate) relation_delete_blocks: u64,
192    pub(crate) write_rows_touched: u64,
193    pub(crate) write_index_entries_changed: u64,
194    pub(crate) write_reverse_index_entries_changed: u64,
195    pub(crate) write_relation_checks: u64,
196    pub(crate) unique_violations: u64,
197    pub(crate) non_atomic_partial_commits: u64,
198    pub(crate) non_atomic_partial_rows_committed: u64,
199}
200
201impl EventOps {
202    #[must_use]
203    pub const fn load_calls(&self) -> u64 {
204        self.load_calls
205    }
206
207    #[must_use]
208    pub const fn save_calls(&self) -> u64 {
209        self.save_calls
210    }
211
212    #[must_use]
213    pub const fn delete_calls(&self) -> u64 {
214        self.delete_calls
215    }
216
217    #[must_use]
218    pub const fn save_insert_calls(&self) -> u64 {
219        self.save_insert_calls
220    }
221
222    #[must_use]
223    pub const fn save_update_calls(&self) -> u64 {
224        self.save_update_calls
225    }
226
227    #[must_use]
228    pub const fn save_replace_calls(&self) -> u64 {
229        self.save_replace_calls
230    }
231
232    #[must_use]
233    pub const fn exec_success(&self) -> u64 {
234        self.exec_success
235    }
236
237    #[must_use]
238    pub const fn exec_error_corruption(&self) -> u64 {
239        self.exec_error_corruption
240    }
241
242    #[must_use]
243    pub const fn exec_error_incompatible_persisted_format(&self) -> u64 {
244        self.exec_error_incompatible_persisted_format
245    }
246
247    #[must_use]
248    pub const fn exec_error_not_found(&self) -> u64 {
249        self.exec_error_not_found
250    }
251
252    #[must_use]
253    pub const fn exec_error_internal(&self) -> u64 {
254        self.exec_error_internal
255    }
256
257    #[must_use]
258    pub const fn exec_error_conflict(&self) -> u64 {
259        self.exec_error_conflict
260    }
261
262    #[must_use]
263    pub const fn exec_error_unsupported(&self) -> u64 {
264        self.exec_error_unsupported
265    }
266
267    #[must_use]
268    pub const fn exec_error_invariant_violation(&self) -> u64 {
269        self.exec_error_invariant_violation
270    }
271
272    #[must_use]
273    pub const fn exec_aborted(&self) -> u64 {
274        self.exec_aborted
275    }
276
277    #[must_use]
278    pub const fn cache_shared_query_plan_hits(&self) -> u64 {
279        self.cache_shared_query_plan_hits
280    }
281
282    #[must_use]
283    pub const fn cache_shared_query_plan_misses(&self) -> u64 {
284        self.cache_shared_query_plan_misses
285    }
286
287    #[must_use]
288    pub const fn cache_shared_query_plan_inserts(&self) -> u64 {
289        self.cache_shared_query_plan_inserts
290    }
291
292    #[must_use]
293    pub const fn cache_shared_query_plan_entries(&self) -> u64 {
294        self.cache_shared_query_plan_entries
295    }
296
297    #[must_use]
298    pub const fn cache_shared_query_plan_miss_cold(&self) -> u64 {
299        self.cache_shared_query_plan_miss_cold
300    }
301
302    #[must_use]
303    pub const fn cache_shared_query_plan_miss_distinct_key(&self) -> u64 {
304        self.cache_shared_query_plan_miss_distinct_key
305    }
306
307    #[must_use]
308    pub const fn cache_shared_query_plan_miss_schema_fingerprint(&self) -> u64 {
309        self.cache_shared_query_plan_miss_schema_fingerprint
310    }
311
312    #[must_use]
313    pub const fn cache_shared_query_plan_miss_visibility(&self) -> u64 {
314        self.cache_shared_query_plan_miss_visibility
315    }
316
317    #[must_use]
318    pub const fn cache_sql_compiled_command_hits(&self) -> u64 {
319        self.cache_sql_compiled_command_hits
320    }
321
322    #[must_use]
323    pub const fn cache_sql_compiled_command_misses(&self) -> u64 {
324        self.cache_sql_compiled_command_misses
325    }
326
327    #[must_use]
328    pub const fn cache_sql_compiled_command_inserts(&self) -> u64 {
329        self.cache_sql_compiled_command_inserts
330    }
331
332    #[must_use]
333    pub const fn cache_sql_compiled_command_entries(&self) -> u64 {
334        self.cache_sql_compiled_command_entries
335    }
336
337    #[must_use]
338    pub const fn cache_sql_compiled_command_miss_cold(&self) -> u64 {
339        self.cache_sql_compiled_command_miss_cold
340    }
341
342    #[must_use]
343    pub const fn cache_sql_compiled_command_miss_distinct_key(&self) -> u64 {
344        self.cache_sql_compiled_command_miss_distinct_key
345    }
346
347    #[must_use]
348    pub const fn cache_sql_compiled_command_miss_schema_fingerprint(&self) -> u64 {
349        self.cache_sql_compiled_command_miss_schema_fingerprint
350    }
351
352    #[must_use]
353    pub const fn cache_sql_compiled_command_miss_surface(&self) -> u64 {
354        self.cache_sql_compiled_command_miss_surface
355    }
356
357    #[must_use]
358    pub const fn schema_reconcile_checks(&self) -> u64 {
359        self.schema_reconcile_checks
360    }
361
362    #[must_use]
363    pub const fn schema_reconcile_exact_match(&self) -> u64 {
364        self.schema_reconcile_exact_match
365    }
366
367    #[must_use]
368    pub const fn schema_reconcile_first_create(&self) -> u64 {
369        self.schema_reconcile_first_create
370    }
371
372    #[must_use]
373    pub const fn schema_reconcile_latest_snapshot_corrupt(&self) -> u64 {
374        self.schema_reconcile_latest_snapshot_corrupt
375    }
376
377    #[must_use]
378    pub const fn schema_reconcile_rejected_field_slot(&self) -> u64 {
379        self.schema_reconcile_rejected_field_slot
380    }
381
382    #[must_use]
383    pub const fn schema_reconcile_rejected_other(&self) -> u64 {
384        self.schema_reconcile_rejected_other
385    }
386
387    #[must_use]
388    pub const fn schema_reconcile_rejected_row_layout(&self) -> u64 {
389        self.schema_reconcile_rejected_row_layout
390    }
391
392    #[must_use]
393    pub const fn schema_reconcile_rejected_schema_version(&self) -> u64 {
394        self.schema_reconcile_rejected_schema_version
395    }
396
397    #[must_use]
398    pub const fn schema_reconcile_store_write_error(&self) -> u64 {
399        self.schema_reconcile_store_write_error
400    }
401
402    #[must_use]
403    pub const fn schema_transition_checks(&self) -> u64 {
404        self.schema_transition_checks
405    }
406
407    #[must_use]
408    pub const fn schema_transition_add_expression_index(&self) -> u64 {
409        self.schema_transition_add_expression_index
410    }
411
412    #[must_use]
413    pub const fn schema_transition_add_field_path_index(&self) -> u64 {
414        self.schema_transition_add_field_path_index
415    }
416
417    #[must_use]
418    pub const fn schema_transition_append_only_nullable_fields(&self) -> u64 {
419        self.schema_transition_append_only_nullable_fields
420    }
421
422    #[must_use]
423    pub const fn schema_transition_exact_match(&self) -> u64 {
424        self.schema_transition_exact_match
425    }
426
427    #[must_use]
428    pub const fn schema_transition_metadata_only_index_rename(&self) -> u64 {
429        self.schema_transition_metadata_only_index_rename
430    }
431
432    #[must_use]
433    pub const fn schema_transition_rejected_entity_identity(&self) -> u64 {
434        self.schema_transition_rejected_entity_identity
435    }
436
437    #[must_use]
438    pub const fn schema_transition_rejected_field_contract(&self) -> u64 {
439        self.schema_transition_rejected_field_contract
440    }
441
442    #[must_use]
443    pub const fn schema_transition_rejected_field_slot(&self) -> u64 {
444        self.schema_transition_rejected_field_slot
445    }
446
447    #[must_use]
448    pub const fn schema_transition_rejected_row_layout(&self) -> u64 {
449        self.schema_transition_rejected_row_layout
450    }
451
452    #[must_use]
453    pub const fn schema_transition_rejected_schema_version(&self) -> u64 {
454        self.schema_transition_rejected_schema_version
455    }
456
457    #[must_use]
458    pub const fn schema_transition_rejected_snapshot(&self) -> u64 {
459        self.schema_transition_rejected_snapshot
460    }
461
462    #[must_use]
463    pub const fn schema_store_snapshots(&self) -> u64 {
464        self.schema_store_snapshots
465    }
466
467    #[must_use]
468    pub const fn schema_store_encoded_bytes(&self) -> u64 {
469        self.schema_store_encoded_bytes
470    }
471
472    #[must_use]
473    pub const fn schema_store_latest_snapshot_bytes(&self) -> u64 {
474        self.schema_store_latest_snapshot_bytes
475    }
476
477    #[must_use]
478    pub const fn accepted_schema_fields(&self) -> u64 {
479        self.accepted_schema_fields
480    }
481
482    #[must_use]
483    pub const fn accepted_schema_nested_leaf_facts(&self) -> u64 {
484        self.accepted_schema_nested_leaf_facts
485    }
486
487    #[must_use]
488    pub const fn sql_compile_rejects(&self) -> u64 {
489        self.sql_compile_rejects
490    }
491
492    #[must_use]
493    pub const fn sql_compile_reject_cache_key(&self) -> u64 {
494        self.sql_compile_reject_cache_key
495    }
496
497    #[must_use]
498    pub const fn sql_compile_reject_parse(&self) -> u64 {
499        self.sql_compile_reject_parse
500    }
501
502    #[must_use]
503    pub const fn sql_compile_reject_semantic(&self) -> u64 {
504        self.sql_compile_reject_semantic
505    }
506
507    #[must_use]
508    pub const fn plan_by_key(&self) -> u64 {
509        self.plan_by_key
510    }
511
512    #[must_use]
513    pub const fn plan_by_keys(&self) -> u64 {
514        self.plan_by_keys
515    }
516
517    #[must_use]
518    pub const fn plan_key_range(&self) -> u64 {
519        self.plan_key_range
520    }
521
522    #[must_use]
523    pub const fn plan_index_branch_set(&self) -> u64 {
524        self.plan_index_branch_set
525    }
526
527    #[must_use]
528    pub const fn plan_index_prefix(&self) -> u64 {
529        self.plan_index_prefix
530    }
531
532    #[must_use]
533    pub const fn plan_index_multi_lookup(&self) -> u64 {
534        self.plan_index_multi_lookup
535    }
536
537    #[must_use]
538    pub const fn plan_index_range(&self) -> u64 {
539        self.plan_index_range
540    }
541
542    #[must_use]
543    pub const fn plan_explicit_full_scan(&self) -> u64 {
544        self.plan_explicit_full_scan
545    }
546
547    #[must_use]
548    pub const fn plan_union(&self) -> u64 {
549        self.plan_union
550    }
551
552    #[must_use]
553    pub const fn plan_intersection(&self) -> u64 {
554        self.plan_intersection
555    }
556
557    #[must_use]
558    pub const fn plan_grouped_hash_materialized(&self) -> u64 {
559        self.plan_grouped_hash_materialized
560    }
561
562    #[must_use]
563    pub const fn plan_grouped_ordered_materialized(&self) -> u64 {
564        self.plan_grouped_ordered_materialized
565    }
566
567    #[must_use]
568    pub const fn plan_choice_conflicting_primary_key_children_access_preferred(&self) -> u64 {
569        self.plan_choice_conflicting_primary_key_children_access_preferred
570    }
571
572    #[must_use]
573    pub const fn plan_choice_constant_false_predicate(&self) -> u64 {
574        self.plan_choice_constant_false_predicate
575    }
576
577    #[must_use]
578    pub const fn plan_choice_empty_child_access_preferred(&self) -> u64 {
579        self.plan_choice_empty_child_access_preferred
580    }
581
582    #[must_use]
583    pub const fn plan_choice_full_scan_access(&self) -> u64 {
584        self.plan_choice_full_scan_access
585    }
586
587    #[must_use]
588    pub const fn plan_choice_intent_key_access_override(&self) -> u64 {
589        self.plan_choice_intent_key_access_override
590    }
591
592    #[must_use]
593    pub const fn plan_choice_limit_zero_window(&self) -> u64 {
594        self.plan_choice_limit_zero_window
595    }
596
597    #[must_use]
598    pub const fn plan_choice_non_index_access(&self) -> u64 {
599        self.plan_choice_non_index_access
600    }
601
602    #[must_use]
603    pub const fn plan_choice_planner_composite_non_index(&self) -> u64 {
604        self.plan_choice_planner_composite_non_index
605    }
606
607    #[must_use]
608    pub const fn plan_choice_planner_full_scan_fallback(&self) -> u64 {
609        self.plan_choice_planner_full_scan_fallback
610    }
611
612    #[must_use]
613    pub const fn plan_choice_planner_key_set_access(&self) -> u64 {
614        self.plan_choice_planner_key_set_access
615    }
616
617    #[must_use]
618    pub const fn plan_choice_planner_primary_key_lookup(&self) -> u64 {
619        self.plan_choice_planner_primary_key_lookup
620    }
621
622    #[must_use]
623    pub const fn plan_choice_planner_primary_key_range(&self) -> u64 {
624        self.plan_choice_planner_primary_key_range
625    }
626
627    #[must_use]
628    pub const fn plan_choice_required_order_primary_key_range_preferred(&self) -> u64 {
629        self.plan_choice_required_order_primary_key_range_preferred
630    }
631
632    #[must_use]
633    pub const fn plan_choice_singleton_primary_key_child_access_preferred(&self) -> u64 {
634        self.plan_choice_singleton_primary_key_child_access_preferred
635    }
636
637    #[must_use]
638    pub const fn prepared_shape_already_finalized(&self) -> u64 {
639        self.prepared_shape_already_finalized
640    }
641
642    #[must_use]
643    pub const fn rows_loaded(&self) -> u64 {
644        self.rows_loaded
645    }
646
647    #[must_use]
648    pub const fn rows_saved(&self) -> u64 {
649        self.rows_saved
650    }
651
652    #[must_use]
653    pub const fn rows_inserted(&self) -> u64 {
654        self.rows_inserted
655    }
656
657    #[must_use]
658    pub const fn rows_updated(&self) -> u64 {
659        self.rows_updated
660    }
661
662    #[must_use]
663    pub const fn rows_replaced(&self) -> u64 {
664        self.rows_replaced
665    }
666
667    #[must_use]
668    pub const fn rows_scanned(&self) -> u64 {
669        self.rows_scanned
670    }
671
672    #[must_use]
673    pub const fn rows_filtered(&self) -> u64 {
674        self.rows_filtered
675    }
676
677    #[must_use]
678    pub const fn rows_aggregated(&self) -> u64 {
679        self.rows_aggregated
680    }
681
682    #[must_use]
683    pub const fn rows_emitted(&self) -> u64 {
684        self.rows_emitted
685    }
686
687    #[must_use]
688    pub const fn load_candidate_rows_scanned(&self) -> u64 {
689        self.load_candidate_rows_scanned
690    }
691
692    #[must_use]
693    pub const fn load_candidate_rows_filtered(&self) -> u64 {
694        self.load_candidate_rows_filtered
695    }
696
697    #[must_use]
698    pub const fn load_result_rows_emitted(&self) -> u64 {
699        self.load_result_rows_emitted
700    }
701
702    #[must_use]
703    pub const fn rows_deleted(&self) -> u64 {
704        self.rows_deleted
705    }
706
707    #[must_use]
708    pub const fn sql_insert_calls(&self) -> u64 {
709        self.sql_insert_calls
710    }
711
712    #[must_use]
713    pub const fn sql_insert_select_calls(&self) -> u64 {
714        self.sql_insert_select_calls
715    }
716
717    #[must_use]
718    pub const fn sql_update_calls(&self) -> u64 {
719        self.sql_update_calls
720    }
721
722    #[must_use]
723    pub const fn sql_delete_calls(&self) -> u64 {
724        self.sql_delete_calls
725    }
726
727    #[must_use]
728    pub const fn sql_write_staged_rows(&self) -> u64 {
729        self.sql_write_staged_rows
730    }
731
732    #[must_use]
733    pub const fn sql_write_matched_rows(&self) -> u64 {
734        self.sql_write_matched_rows
735    }
736
737    #[must_use]
738    pub const fn sql_write_mutated_rows(&self) -> u64 {
739        self.sql_write_mutated_rows
740    }
741
742    #[must_use]
743    pub const fn sql_write_returning_rows(&self) -> u64 {
744        self.sql_write_returning_rows
745    }
746
747    #[must_use]
748    pub const fn sql_write_error_insert(&self) -> u64 {
749        self.sql_write_error_insert
750    }
751
752    #[must_use]
753    pub const fn sql_write_error_insert_select(&self) -> u64 {
754        self.sql_write_error_insert_select
755    }
756
757    #[must_use]
758    pub const fn sql_write_error_update(&self) -> u64 {
759        self.sql_write_error_update
760    }
761
762    #[must_use]
763    pub const fn sql_write_error_delete(&self) -> u64 {
764        self.sql_write_error_delete
765    }
766
767    #[must_use]
768    pub const fn sql_write_error_corruption(&self) -> u64 {
769        self.sql_write_error_corruption
770    }
771
772    #[must_use]
773    pub const fn sql_write_error_incompatible_persisted_format(&self) -> u64 {
774        self.sql_write_error_incompatible_persisted_format
775    }
776
777    #[must_use]
778    pub const fn sql_write_error_not_found(&self) -> u64 {
779        self.sql_write_error_not_found
780    }
781
782    #[must_use]
783    pub const fn sql_write_error_internal(&self) -> u64 {
784        self.sql_write_error_internal
785    }
786
787    #[must_use]
788    pub const fn sql_write_error_conflict(&self) -> u64 {
789        self.sql_write_error_conflict
790    }
791
792    #[must_use]
793    pub const fn sql_write_error_unsupported(&self) -> u64 {
794        self.sql_write_error_unsupported
795    }
796
797    #[must_use]
798    pub const fn sql_write_error_invariant_violation(&self) -> u64 {
799        self.sql_write_error_invariant_violation
800    }
801
802    #[must_use]
803    pub const fn index_inserts(&self) -> u64 {
804        self.index_inserts
805    }
806
807    #[must_use]
808    pub const fn index_removes(&self) -> u64 {
809        self.index_removes
810    }
811
812    #[must_use]
813    pub const fn reverse_index_inserts(&self) -> u64 {
814        self.reverse_index_inserts
815    }
816
817    #[must_use]
818    pub const fn reverse_index_removes(&self) -> u64 {
819        self.reverse_index_removes
820    }
821
822    #[must_use]
823    pub const fn relation_reverse_lookups(&self) -> u64 {
824        self.relation_reverse_lookups
825    }
826
827    #[must_use]
828    pub const fn relation_delete_blocks(&self) -> u64 {
829        self.relation_delete_blocks
830    }
831
832    #[must_use]
833    pub const fn write_rows_touched(&self) -> u64 {
834        self.write_rows_touched
835    }
836
837    #[must_use]
838    pub const fn write_index_entries_changed(&self) -> u64 {
839        self.write_index_entries_changed
840    }
841
842    #[must_use]
843    pub const fn write_reverse_index_entries_changed(&self) -> u64 {
844        self.write_reverse_index_entries_changed
845    }
846
847    #[must_use]
848    pub const fn write_relation_checks(&self) -> u64 {
849        self.write_relation_checks
850    }
851
852    #[must_use]
853    pub const fn unique_violations(&self) -> u64 {
854        self.unique_violations
855    }
856
857    #[must_use]
858    pub const fn non_atomic_partial_commits(&self) -> u64 {
859        self.non_atomic_partial_commits
860    }
861
862    #[must_use]
863    pub const fn non_atomic_partial_rows_committed(&self) -> u64 {
864        self.non_atomic_partial_rows_committed
865    }
866
867    /// Returns result rows emitted per load candidate row scanned.
868    #[must_use]
869    pub const fn load_selectivity_ratio(&self) -> Option<MetricRatio> {
870        ratio(
871            self.load_result_rows_emitted,
872            self.load_candidate_rows_scanned,
873        )
874    }
875
876    /// Returns candidate rows filtered per load candidate row scanned.
877    #[must_use]
878    pub const fn load_filter_ratio(&self) -> Option<MetricRatio> {
879        ratio(
880            self.load_candidate_rows_filtered,
881            self.load_candidate_rows_scanned,
882        )
883    }
884
885    /// Returns SQL-mutated rows per SQL-matched row.
886    #[must_use]
887    pub const fn sql_write_mutation_ratio(&self) -> Option<MetricRatio> {
888        ratio(self.sql_write_mutated_rows, self.sql_write_matched_rows)
889    }
890
891    /// Returns SQL `RETURNING` rows per SQL-mutated row.
892    #[must_use]
893    pub const fn sql_write_returning_ratio(&self) -> Option<MetricRatio> {
894        ratio(self.sql_write_returning_rows, self.sql_write_mutated_rows)
895    }
896
897    /// Returns primary index entries changed per write row touched.
898    #[must_use]
899    pub const fn write_index_entries_per_row(&self) -> Option<MetricRatio> {
900        ratio(self.write_index_entries_changed, self.write_rows_touched)
901    }
902
903    /// Returns reverse-index entries changed per write row touched.
904    #[must_use]
905    pub const fn write_reverse_index_entries_per_row(&self) -> Option<MetricRatio> {
906        ratio(
907            self.write_reverse_index_entries_changed,
908            self.write_rows_touched,
909        )
910    }
911
912    /// Returns relation checks performed per write row touched.
913    #[must_use]
914    pub const fn write_relation_checks_per_row(&self) -> Option<MetricRatio> {
915        ratio(self.write_relation_checks, self.write_rows_touched)
916    }
917}