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