Skip to main content

icydb_core/metrics/state/
summary.rs

1//! Module: metrics::state::summary
2//! Responsibility: rich per-entity metrics summary DTO and projection.
3//! Does not own: mutable metrics state updates or top-level report windows.
4//! Boundary: keeps per-entity rich report payload shape separate from raw state.
5
6use candid::CandidType;
7use serde::Deserialize;
8
9use super::{EntityCounters, MetricRatio, ratio};
10
11#[cfg_attr(doc, doc = "EntitySummary\n\nPer-entity metrics summary.")]
12#[derive(CandidType, Clone, Debug, Default, Deserialize)]
13pub struct EntitySummary {
14    path: String,
15    load_calls: u64,
16    save_calls: u64,
17    delete_calls: u64,
18    save_insert_calls: u64,
19    save_update_calls: u64,
20    save_replace_calls: u64,
21    exec_success: u64,
22    exec_error_corruption: u64,
23    exec_error_incompatible_persisted_format: u64,
24    exec_error_not_found: u64,
25    exec_error_internal: u64,
26    exec_error_conflict: u64,
27    exec_error_unsupported: u64,
28    exec_error_invariant_violation: u64,
29    exec_aborted: u64,
30    cache_shared_query_plan_hits: u64,
31    cache_shared_query_plan_misses: u64,
32    cache_shared_query_plan_inserts: u64,
33    cache_shared_query_plan_miss_cold: u64,
34    cache_shared_query_plan_miss_distinct_key: u64,
35    cache_shared_query_plan_miss_schema_fingerprint: u64,
36    cache_shared_query_plan_miss_visibility: u64,
37    cache_sql_compiled_command_hits: u64,
38    cache_sql_compiled_command_misses: u64,
39    cache_sql_compiled_command_inserts: u64,
40    cache_sql_compiled_command_miss_cold: u64,
41    cache_sql_compiled_command_miss_distinct_key: u64,
42    cache_sql_compiled_command_miss_schema_fingerprint: u64,
43    cache_sql_compiled_command_miss_surface: u64,
44    schema_reconcile_checks: u64,
45    schema_reconcile_exact_match: u64,
46    schema_reconcile_first_create: u64,
47    schema_reconcile_latest_snapshot_corrupt: u64,
48    schema_reconcile_rejected_field_slot: u64,
49    schema_reconcile_rejected_other: u64,
50    schema_reconcile_rejected_row_layout: u64,
51    schema_reconcile_rejected_schema_version: u64,
52    schema_reconcile_store_write_error: u64,
53    schema_transition_checks: u64,
54    schema_transition_add_expression_index: u64,
55    schema_transition_add_field_path_index: u64,
56    schema_transition_append_only_fields: u64,
57    schema_transition_constraint_activation: u64,
58    schema_transition_exact_match: u64,
59    schema_transition_metadata_only_field_default: u64,
60    schema_transition_metadata_only_index_rename: u64,
61    schema_transition_rejected_entity_identity: u64,
62    schema_transition_rejected_field_contract: u64,
63    schema_transition_rejected_field_slot: u64,
64    schema_transition_rejected_row_layout: u64,
65    schema_transition_rejected_schema_version: u64,
66    schema_transition_rejected_snapshot: u64,
67    schema_store_snapshots: u64,
68    schema_store_encoded_bytes: u64,
69    schema_store_latest_snapshot_bytes: u64,
70    accepted_schema_fields: u64,
71    accepted_schema_nested_leaf_facts: u64,
72    sql_compile_rejects: u64,
73    sql_compile_reject_cache_key: u64,
74    sql_compile_reject_parse: u64,
75    sql_compile_reject_semantic: u64,
76    plan_by_key: u64,
77    plan_by_keys: u64,
78    plan_key_range: u64,
79    plan_index_branch_set: u64,
80    plan_index_prefix: u64,
81    plan_index_multi_lookup: u64,
82    plan_index_range: u64,
83    plan_explicit_full_scan: u64,
84    plan_union: u64,
85    plan_intersection: u64,
86    plan_grouped_hash_materialized: u64,
87    plan_grouped_ordered_streaming: u64,
88    plan_choice_conflicting_primary_key_children_access_preferred: u64,
89    plan_choice_constant_false_predicate: u64,
90    plan_choice_empty_child_access_preferred: u64,
91    plan_choice_full_scan_access: u64,
92    plan_choice_intent_key_access_override: u64,
93    plan_choice_limit_zero_window: u64,
94    plan_choice_non_index_access: u64,
95    plan_choice_planner_composite_non_index: u64,
96    plan_choice_planner_full_scan_fallback: u64,
97    plan_choice_planner_key_set_access: u64,
98    plan_choice_planner_primary_key_lookup: u64,
99    plan_choice_planner_primary_key_range: u64,
100    plan_choice_required_order_primary_key_range_preferred: u64,
101    plan_choice_singleton_primary_key_child_access_preferred: u64,
102    prepared_shape_already_finalized: u64,
103    rows_loaded: u64,
104    rows_saved: u64,
105    rows_inserted: u64,
106    rows_updated: u64,
107    rows_replaced: u64,
108    rows_scanned: u64,
109    rows_filtered: u64,
110    rows_aggregated: u64,
111    rows_emitted: u64,
112    load_candidate_rows_scanned: u64,
113    load_candidate_rows_filtered: u64,
114    load_result_rows_emitted: u64,
115    rows_deleted: u64,
116    sql_insert_calls: u64,
117    sql_insert_select_calls: u64,
118    sql_update_calls: u64,
119    sql_delete_calls: u64,
120    sql_write_staged_rows: u64,
121    sql_write_matched_rows: u64,
122    sql_write_mutated_rows: u64,
123    sql_write_returning_rows: u64,
124    sql_write_error_insert: u64,
125    sql_write_error_insert_select: u64,
126    sql_write_error_update: u64,
127    sql_write_error_delete: u64,
128    sql_write_error_corruption: u64,
129    sql_write_error_incompatible_persisted_format: u64,
130    sql_write_error_not_found: u64,
131    sql_write_error_internal: u64,
132    sql_write_error_conflict: u64,
133    sql_write_error_unsupported: u64,
134    sql_write_error_invariant_violation: u64,
135    index_inserts: u64,
136    index_removes: u64,
137    reverse_index_inserts: u64,
138    reverse_index_removes: u64,
139    relation_reverse_lookups: u64,
140    relation_delete_blocks: u64,
141    write_rows_touched: u64,
142    write_index_entries_changed: u64,
143    write_reverse_index_entries_changed: u64,
144    write_relation_checks: u64,
145    unique_violations: u64,
146    non_atomic_partial_commits: u64,
147    non_atomic_partial_rows_committed: u64,
148}
149
150impl EntitySummary {
151    #[must_use]
152    pub const fn path(&self) -> &str {
153        self.path.as_str()
154    }
155
156    #[must_use]
157    pub const fn load_calls(&self) -> u64 {
158        self.load_calls
159    }
160
161    #[must_use]
162    pub const fn save_calls(&self) -> u64 {
163        self.save_calls
164    }
165
166    #[must_use]
167    pub const fn delete_calls(&self) -> u64 {
168        self.delete_calls
169    }
170
171    #[must_use]
172    pub const fn save_insert_calls(&self) -> u64 {
173        self.save_insert_calls
174    }
175
176    #[must_use]
177    pub const fn save_update_calls(&self) -> u64 {
178        self.save_update_calls
179    }
180
181    #[must_use]
182    pub const fn save_replace_calls(&self) -> u64 {
183        self.save_replace_calls
184    }
185
186    #[must_use]
187    pub const fn exec_success(&self) -> u64 {
188        self.exec_success
189    }
190
191    #[must_use]
192    pub const fn exec_error_corruption(&self) -> u64 {
193        self.exec_error_corruption
194    }
195
196    #[must_use]
197    pub const fn exec_error_incompatible_persisted_format(&self) -> u64 {
198        self.exec_error_incompatible_persisted_format
199    }
200
201    #[must_use]
202    pub const fn exec_error_not_found(&self) -> u64 {
203        self.exec_error_not_found
204    }
205
206    #[must_use]
207    pub const fn exec_error_internal(&self) -> u64 {
208        self.exec_error_internal
209    }
210
211    #[must_use]
212    pub const fn exec_error_conflict(&self) -> u64 {
213        self.exec_error_conflict
214    }
215
216    #[must_use]
217    pub const fn exec_error_unsupported(&self) -> u64 {
218        self.exec_error_unsupported
219    }
220
221    #[must_use]
222    pub const fn exec_error_invariant_violation(&self) -> u64 {
223        self.exec_error_invariant_violation
224    }
225
226    #[must_use]
227    pub const fn exec_aborted(&self) -> u64 {
228        self.exec_aborted
229    }
230
231    #[must_use]
232    pub const fn cache_shared_query_plan_hits(&self) -> u64 {
233        self.cache_shared_query_plan_hits
234    }
235
236    #[must_use]
237    pub const fn cache_shared_query_plan_misses(&self) -> u64 {
238        self.cache_shared_query_plan_misses
239    }
240
241    #[must_use]
242    pub const fn cache_shared_query_plan_inserts(&self) -> u64 {
243        self.cache_shared_query_plan_inserts
244    }
245
246    #[must_use]
247    pub const fn cache_shared_query_plan_miss_cold(&self) -> u64 {
248        self.cache_shared_query_plan_miss_cold
249    }
250
251    #[must_use]
252    pub const fn cache_shared_query_plan_miss_distinct_key(&self) -> u64 {
253        self.cache_shared_query_plan_miss_distinct_key
254    }
255
256    #[must_use]
257    pub const fn cache_shared_query_plan_miss_schema_fingerprint(&self) -> u64 {
258        self.cache_shared_query_plan_miss_schema_fingerprint
259    }
260
261    #[must_use]
262    pub const fn cache_shared_query_plan_miss_visibility(&self) -> u64 {
263        self.cache_shared_query_plan_miss_visibility
264    }
265
266    #[must_use]
267    pub const fn cache_sql_compiled_command_hits(&self) -> u64 {
268        self.cache_sql_compiled_command_hits
269    }
270
271    #[must_use]
272    pub const fn cache_sql_compiled_command_misses(&self) -> u64 {
273        self.cache_sql_compiled_command_misses
274    }
275
276    #[must_use]
277    pub const fn cache_sql_compiled_command_inserts(&self) -> u64 {
278        self.cache_sql_compiled_command_inserts
279    }
280
281    #[must_use]
282    pub const fn cache_sql_compiled_command_miss_cold(&self) -> u64 {
283        self.cache_sql_compiled_command_miss_cold
284    }
285
286    #[must_use]
287    pub const fn cache_sql_compiled_command_miss_distinct_key(&self) -> u64 {
288        self.cache_sql_compiled_command_miss_distinct_key
289    }
290
291    #[must_use]
292    pub const fn cache_sql_compiled_command_miss_schema_fingerprint(&self) -> u64 {
293        self.cache_sql_compiled_command_miss_schema_fingerprint
294    }
295
296    #[must_use]
297    pub const fn cache_sql_compiled_command_miss_surface(&self) -> u64 {
298        self.cache_sql_compiled_command_miss_surface
299    }
300
301    #[must_use]
302    pub const fn schema_reconcile_checks(&self) -> u64 {
303        self.schema_reconcile_checks
304    }
305
306    #[must_use]
307    pub const fn schema_reconcile_exact_match(&self) -> u64 {
308        self.schema_reconcile_exact_match
309    }
310
311    #[must_use]
312    pub const fn schema_reconcile_first_create(&self) -> u64 {
313        self.schema_reconcile_first_create
314    }
315
316    #[must_use]
317    pub const fn schema_reconcile_latest_snapshot_corrupt(&self) -> u64 {
318        self.schema_reconcile_latest_snapshot_corrupt
319    }
320
321    #[must_use]
322    pub const fn schema_reconcile_rejected_field_slot(&self) -> u64 {
323        self.schema_reconcile_rejected_field_slot
324    }
325
326    #[must_use]
327    pub const fn schema_reconcile_rejected_other(&self) -> u64 {
328        self.schema_reconcile_rejected_other
329    }
330
331    #[must_use]
332    pub const fn schema_reconcile_rejected_row_layout(&self) -> u64 {
333        self.schema_reconcile_rejected_row_layout
334    }
335
336    #[must_use]
337    pub const fn schema_reconcile_rejected_schema_version(&self) -> u64 {
338        self.schema_reconcile_rejected_schema_version
339    }
340
341    #[must_use]
342    pub const fn schema_reconcile_store_write_error(&self) -> u64 {
343        self.schema_reconcile_store_write_error
344    }
345
346    #[must_use]
347    pub const fn schema_transition_checks(&self) -> u64 {
348        self.schema_transition_checks
349    }
350
351    #[must_use]
352    pub const fn schema_transition_add_expression_index(&self) -> u64 {
353        self.schema_transition_add_expression_index
354    }
355
356    #[must_use]
357    pub const fn schema_transition_add_field_path_index(&self) -> u64 {
358        self.schema_transition_add_field_path_index
359    }
360
361    #[must_use]
362    pub const fn schema_transition_append_only_fields(&self) -> u64 {
363        self.schema_transition_append_only_fields
364    }
365
366    #[must_use]
367    pub const fn schema_transition_constraint_activation(&self) -> u64 {
368        self.schema_transition_constraint_activation
369    }
370
371    #[must_use]
372    pub const fn schema_transition_exact_match(&self) -> u64 {
373        self.schema_transition_exact_match
374    }
375
376    #[must_use]
377    pub const fn schema_transition_metadata_only_field_default(&self) -> u64 {
378        self.schema_transition_metadata_only_field_default
379    }
380
381    #[must_use]
382    pub const fn schema_transition_metadata_only_index_rename(&self) -> u64 {
383        self.schema_transition_metadata_only_index_rename
384    }
385
386    #[must_use]
387    pub const fn schema_transition_rejected_entity_identity(&self) -> u64 {
388        self.schema_transition_rejected_entity_identity
389    }
390
391    #[must_use]
392    pub const fn schema_transition_rejected_field_contract(&self) -> u64 {
393        self.schema_transition_rejected_field_contract
394    }
395
396    #[must_use]
397    pub const fn schema_transition_rejected_field_slot(&self) -> u64 {
398        self.schema_transition_rejected_field_slot
399    }
400
401    #[must_use]
402    pub const fn schema_transition_rejected_row_layout(&self) -> u64 {
403        self.schema_transition_rejected_row_layout
404    }
405
406    #[must_use]
407    pub const fn schema_transition_rejected_schema_version(&self) -> u64 {
408        self.schema_transition_rejected_schema_version
409    }
410
411    #[must_use]
412    pub const fn schema_transition_rejected_snapshot(&self) -> u64 {
413        self.schema_transition_rejected_snapshot
414    }
415
416    #[must_use]
417    pub const fn schema_store_snapshots(&self) -> u64 {
418        self.schema_store_snapshots
419    }
420
421    #[must_use]
422    pub const fn schema_store_encoded_bytes(&self) -> u64 {
423        self.schema_store_encoded_bytes
424    }
425
426    #[must_use]
427    pub const fn schema_store_latest_snapshot_bytes(&self) -> u64 {
428        self.schema_store_latest_snapshot_bytes
429    }
430
431    #[must_use]
432    pub const fn accepted_schema_fields(&self) -> u64 {
433        self.accepted_schema_fields
434    }
435
436    #[must_use]
437    pub const fn accepted_schema_nested_leaf_facts(&self) -> u64 {
438        self.accepted_schema_nested_leaf_facts
439    }
440
441    #[must_use]
442    pub const fn sql_compile_rejects(&self) -> u64 {
443        self.sql_compile_rejects
444    }
445
446    #[must_use]
447    pub const fn sql_compile_reject_cache_key(&self) -> u64 {
448        self.sql_compile_reject_cache_key
449    }
450
451    #[must_use]
452    pub const fn sql_compile_reject_parse(&self) -> u64 {
453        self.sql_compile_reject_parse
454    }
455
456    #[must_use]
457    pub const fn sql_compile_reject_semantic(&self) -> u64 {
458        self.sql_compile_reject_semantic
459    }
460
461    #[must_use]
462    pub const fn plan_by_key(&self) -> u64 {
463        self.plan_by_key
464    }
465
466    #[must_use]
467    pub const fn plan_by_keys(&self) -> u64 {
468        self.plan_by_keys
469    }
470
471    #[must_use]
472    pub const fn plan_key_range(&self) -> u64 {
473        self.plan_key_range
474    }
475
476    #[must_use]
477    pub const fn plan_index_branch_set(&self) -> u64 {
478        self.plan_index_branch_set
479    }
480
481    #[must_use]
482    pub const fn plan_index_prefix(&self) -> u64 {
483        self.plan_index_prefix
484    }
485
486    #[must_use]
487    pub const fn plan_index_multi_lookup(&self) -> u64 {
488        self.plan_index_multi_lookup
489    }
490
491    #[must_use]
492    pub const fn plan_index_range(&self) -> u64 {
493        self.plan_index_range
494    }
495
496    #[must_use]
497    pub const fn plan_explicit_full_scan(&self) -> u64 {
498        self.plan_explicit_full_scan
499    }
500
501    #[must_use]
502    pub const fn plan_union(&self) -> u64 {
503        self.plan_union
504    }
505
506    #[must_use]
507    pub const fn plan_intersection(&self) -> u64 {
508        self.plan_intersection
509    }
510
511    #[must_use]
512    pub const fn plan_grouped_hash_materialized(&self) -> u64 {
513        self.plan_grouped_hash_materialized
514    }
515
516    #[must_use]
517    pub const fn plan_grouped_ordered_streaming(&self) -> u64 {
518        self.plan_grouped_ordered_streaming
519    }
520
521    #[must_use]
522    pub const fn plan_choice_conflicting_primary_key_children_access_preferred(&self) -> u64 {
523        self.plan_choice_conflicting_primary_key_children_access_preferred
524    }
525
526    #[must_use]
527    pub const fn plan_choice_constant_false_predicate(&self) -> u64 {
528        self.plan_choice_constant_false_predicate
529    }
530
531    #[must_use]
532    pub const fn plan_choice_empty_child_access_preferred(&self) -> u64 {
533        self.plan_choice_empty_child_access_preferred
534    }
535
536    #[must_use]
537    pub const fn plan_choice_full_scan_access(&self) -> u64 {
538        self.plan_choice_full_scan_access
539    }
540
541    #[must_use]
542    pub const fn plan_choice_intent_key_access_override(&self) -> u64 {
543        self.plan_choice_intent_key_access_override
544    }
545
546    #[must_use]
547    pub const fn plan_choice_limit_zero_window(&self) -> u64 {
548        self.plan_choice_limit_zero_window
549    }
550
551    #[must_use]
552    pub const fn plan_choice_non_index_access(&self) -> u64 {
553        self.plan_choice_non_index_access
554    }
555
556    #[must_use]
557    pub const fn plan_choice_planner_composite_non_index(&self) -> u64 {
558        self.plan_choice_planner_composite_non_index
559    }
560
561    #[must_use]
562    pub const fn plan_choice_planner_full_scan_fallback(&self) -> u64 {
563        self.plan_choice_planner_full_scan_fallback
564    }
565
566    #[must_use]
567    pub const fn plan_choice_planner_key_set_access(&self) -> u64 {
568        self.plan_choice_planner_key_set_access
569    }
570
571    #[must_use]
572    pub const fn plan_choice_planner_primary_key_lookup(&self) -> u64 {
573        self.plan_choice_planner_primary_key_lookup
574    }
575
576    #[must_use]
577    pub const fn plan_choice_planner_primary_key_range(&self) -> u64 {
578        self.plan_choice_planner_primary_key_range
579    }
580
581    #[must_use]
582    pub const fn plan_choice_required_order_primary_key_range_preferred(&self) -> u64 {
583        self.plan_choice_required_order_primary_key_range_preferred
584    }
585
586    #[must_use]
587    pub const fn plan_choice_singleton_primary_key_child_access_preferred(&self) -> u64 {
588        self.plan_choice_singleton_primary_key_child_access_preferred
589    }
590
591    #[must_use]
592    pub const fn prepared_shape_already_finalized(&self) -> u64 {
593        self.prepared_shape_already_finalized
594    }
595
596    #[must_use]
597    pub const fn rows_loaded(&self) -> u64 {
598        self.rows_loaded
599    }
600
601    #[must_use]
602    pub const fn rows_saved(&self) -> u64 {
603        self.rows_saved
604    }
605
606    #[must_use]
607    pub const fn rows_inserted(&self) -> u64 {
608        self.rows_inserted
609    }
610
611    #[must_use]
612    pub const fn rows_updated(&self) -> u64 {
613        self.rows_updated
614    }
615
616    #[must_use]
617    pub const fn rows_replaced(&self) -> u64 {
618        self.rows_replaced
619    }
620
621    #[must_use]
622    pub const fn rows_scanned(&self) -> u64 {
623        self.rows_scanned
624    }
625
626    #[must_use]
627    pub const fn rows_filtered(&self) -> u64 {
628        self.rows_filtered
629    }
630
631    #[must_use]
632    pub const fn rows_aggregated(&self) -> u64 {
633        self.rows_aggregated
634    }
635
636    #[must_use]
637    pub const fn rows_emitted(&self) -> u64 {
638        self.rows_emitted
639    }
640
641    #[must_use]
642    pub const fn load_candidate_rows_scanned(&self) -> u64 {
643        self.load_candidate_rows_scanned
644    }
645
646    #[must_use]
647    pub const fn load_candidate_rows_filtered(&self) -> u64 {
648        self.load_candidate_rows_filtered
649    }
650
651    #[must_use]
652    pub const fn load_result_rows_emitted(&self) -> u64 {
653        self.load_result_rows_emitted
654    }
655
656    #[must_use]
657    pub const fn rows_deleted(&self) -> u64 {
658        self.rows_deleted
659    }
660
661    #[must_use]
662    pub const fn sql_insert_calls(&self) -> u64 {
663        self.sql_insert_calls
664    }
665
666    #[must_use]
667    pub const fn sql_insert_select_calls(&self) -> u64 {
668        self.sql_insert_select_calls
669    }
670
671    #[must_use]
672    pub const fn sql_update_calls(&self) -> u64 {
673        self.sql_update_calls
674    }
675
676    #[must_use]
677    pub const fn sql_delete_calls(&self) -> u64 {
678        self.sql_delete_calls
679    }
680
681    #[must_use]
682    pub const fn sql_write_staged_rows(&self) -> u64 {
683        self.sql_write_staged_rows
684    }
685
686    #[must_use]
687    pub const fn sql_write_matched_rows(&self) -> u64 {
688        self.sql_write_matched_rows
689    }
690
691    #[must_use]
692    pub const fn sql_write_mutated_rows(&self) -> u64 {
693        self.sql_write_mutated_rows
694    }
695
696    #[must_use]
697    pub const fn sql_write_returning_rows(&self) -> u64 {
698        self.sql_write_returning_rows
699    }
700
701    #[must_use]
702    pub const fn sql_write_error_insert(&self) -> u64 {
703        self.sql_write_error_insert
704    }
705
706    #[must_use]
707    pub const fn sql_write_error_insert_select(&self) -> u64 {
708        self.sql_write_error_insert_select
709    }
710
711    #[must_use]
712    pub const fn sql_write_error_update(&self) -> u64 {
713        self.sql_write_error_update
714    }
715
716    #[must_use]
717    pub const fn sql_write_error_delete(&self) -> u64 {
718        self.sql_write_error_delete
719    }
720
721    #[must_use]
722    pub const fn sql_write_error_corruption(&self) -> u64 {
723        self.sql_write_error_corruption
724    }
725
726    #[must_use]
727    pub const fn sql_write_error_incompatible_persisted_format(&self) -> u64 {
728        self.sql_write_error_incompatible_persisted_format
729    }
730
731    #[must_use]
732    pub const fn sql_write_error_not_found(&self) -> u64 {
733        self.sql_write_error_not_found
734    }
735
736    #[must_use]
737    pub const fn sql_write_error_internal(&self) -> u64 {
738        self.sql_write_error_internal
739    }
740
741    #[must_use]
742    pub const fn sql_write_error_conflict(&self) -> u64 {
743        self.sql_write_error_conflict
744    }
745
746    #[must_use]
747    pub const fn sql_write_error_unsupported(&self) -> u64 {
748        self.sql_write_error_unsupported
749    }
750
751    #[must_use]
752    pub const fn sql_write_error_invariant_violation(&self) -> u64 {
753        self.sql_write_error_invariant_violation
754    }
755
756    #[must_use]
757    pub const fn index_inserts(&self) -> u64 {
758        self.index_inserts
759    }
760
761    #[must_use]
762    pub const fn index_removes(&self) -> u64 {
763        self.index_removes
764    }
765
766    #[must_use]
767    pub const fn reverse_index_inserts(&self) -> u64 {
768        self.reverse_index_inserts
769    }
770
771    #[must_use]
772    pub const fn reverse_index_removes(&self) -> u64 {
773        self.reverse_index_removes
774    }
775
776    #[must_use]
777    pub const fn relation_reverse_lookups(&self) -> u64 {
778        self.relation_reverse_lookups
779    }
780
781    #[must_use]
782    pub const fn relation_delete_blocks(&self) -> u64 {
783        self.relation_delete_blocks
784    }
785
786    #[must_use]
787    pub const fn write_rows_touched(&self) -> u64 {
788        self.write_rows_touched
789    }
790
791    #[must_use]
792    pub const fn write_index_entries_changed(&self) -> u64 {
793        self.write_index_entries_changed
794    }
795
796    #[must_use]
797    pub const fn write_reverse_index_entries_changed(&self) -> u64 {
798        self.write_reverse_index_entries_changed
799    }
800
801    #[must_use]
802    pub const fn write_relation_checks(&self) -> u64 {
803        self.write_relation_checks
804    }
805
806    #[must_use]
807    pub const fn unique_violations(&self) -> u64 {
808        self.unique_violations
809    }
810
811    #[must_use]
812    pub const fn non_atomic_partial_commits(&self) -> u64 {
813        self.non_atomic_partial_commits
814    }
815
816    #[must_use]
817    pub const fn non_atomic_partial_rows_committed(&self) -> u64 {
818        self.non_atomic_partial_rows_committed
819    }
820
821    /// Returns result rows emitted per load candidate row scanned.
822    #[must_use]
823    pub const fn load_selectivity_ratio(&self) -> Option<MetricRatio> {
824        ratio(
825            self.load_result_rows_emitted,
826            self.load_candidate_rows_scanned,
827        )
828    }
829
830    /// Returns candidate rows filtered per load candidate row scanned.
831    #[must_use]
832    pub const fn load_filter_ratio(&self) -> Option<MetricRatio> {
833        ratio(
834            self.load_candidate_rows_filtered,
835            self.load_candidate_rows_scanned,
836        )
837    }
838
839    /// Returns SQL-mutated rows per SQL-matched row.
840    #[must_use]
841    pub const fn sql_write_mutation_ratio(&self) -> Option<MetricRatio> {
842        ratio(self.sql_write_mutated_rows, self.sql_write_matched_rows)
843    }
844
845    /// Returns SQL `RETURNING` rows per SQL-mutated row.
846    #[must_use]
847    pub const fn sql_write_returning_ratio(&self) -> Option<MetricRatio> {
848        ratio(self.sql_write_returning_rows, self.sql_write_mutated_rows)
849    }
850
851    /// Returns primary index entries changed per write row touched.
852    #[must_use]
853    pub const fn write_index_entries_per_row(&self) -> Option<MetricRatio> {
854        ratio(self.write_index_entries_changed, self.write_rows_touched)
855    }
856
857    /// Returns reverse-index entries changed per write row touched.
858    #[must_use]
859    pub const fn write_reverse_index_entries_per_row(&self) -> Option<MetricRatio> {
860        ratio(
861            self.write_reverse_index_entries_changed,
862            self.write_rows_touched,
863        )
864    }
865
866    /// Returns relation checks performed per write row touched.
867    #[must_use]
868    pub const fn write_relation_checks_per_row(&self) -> Option<MetricRatio> {
869        ratio(self.write_relation_checks, self.write_rows_touched)
870    }
871
872    // Rank entity summaries by all visible activity so write-heavy or
873    // maintenance-heavy entities are not hidden below read-heavy entities.
874    #[expect(clippy::too_many_lines)]
875    pub(in crate::metrics) const fn activity_score(&self) -> u64 {
876        self.load_calls
877            .saturating_add(self.save_calls)
878            .saturating_add(self.delete_calls)
879            .saturating_add(self.save_insert_calls)
880            .saturating_add(self.save_update_calls)
881            .saturating_add(self.save_replace_calls)
882            .saturating_add(self.exec_success)
883            .saturating_add(self.exec_error_corruption)
884            .saturating_add(self.exec_error_incompatible_persisted_format)
885            .saturating_add(self.exec_error_not_found)
886            .saturating_add(self.exec_error_internal)
887            .saturating_add(self.exec_error_conflict)
888            .saturating_add(self.exec_error_unsupported)
889            .saturating_add(self.exec_error_invariant_violation)
890            .saturating_add(self.exec_aborted)
891            .saturating_add(self.cache_shared_query_plan_hits)
892            .saturating_add(self.cache_shared_query_plan_misses)
893            .saturating_add(self.cache_shared_query_plan_inserts)
894            .saturating_add(self.cache_shared_query_plan_miss_cold)
895            .saturating_add(self.cache_shared_query_plan_miss_distinct_key)
896            .saturating_add(self.cache_shared_query_plan_miss_schema_fingerprint)
897            .saturating_add(self.cache_shared_query_plan_miss_visibility)
898            .saturating_add(self.cache_sql_compiled_command_hits)
899            .saturating_add(self.cache_sql_compiled_command_misses)
900            .saturating_add(self.cache_sql_compiled_command_inserts)
901            .saturating_add(self.cache_sql_compiled_command_miss_cold)
902            .saturating_add(self.cache_sql_compiled_command_miss_distinct_key)
903            .saturating_add(self.cache_sql_compiled_command_miss_schema_fingerprint)
904            .saturating_add(self.cache_sql_compiled_command_miss_surface)
905            .saturating_add(self.schema_reconcile_checks)
906            .saturating_add(self.schema_reconcile_exact_match)
907            .saturating_add(self.schema_reconcile_first_create)
908            .saturating_add(self.schema_reconcile_latest_snapshot_corrupt)
909            .saturating_add(self.schema_reconcile_rejected_field_slot)
910            .saturating_add(self.schema_reconcile_rejected_other)
911            .saturating_add(self.schema_reconcile_rejected_row_layout)
912            .saturating_add(self.schema_reconcile_rejected_schema_version)
913            .saturating_add(self.schema_reconcile_store_write_error)
914            .saturating_add(self.schema_transition_checks)
915            .saturating_add(self.schema_transition_add_expression_index)
916            .saturating_add(self.schema_transition_add_field_path_index)
917            .saturating_add(self.schema_transition_append_only_fields)
918            .saturating_add(self.schema_transition_constraint_activation)
919            .saturating_add(self.schema_transition_exact_match)
920            .saturating_add(self.schema_transition_metadata_only_field_default)
921            .saturating_add(self.schema_transition_metadata_only_index_rename)
922            .saturating_add(self.schema_transition_rejected_entity_identity)
923            .saturating_add(self.schema_transition_rejected_field_contract)
924            .saturating_add(self.schema_transition_rejected_field_slot)
925            .saturating_add(self.schema_transition_rejected_row_layout)
926            .saturating_add(self.schema_transition_rejected_schema_version)
927            .saturating_add(self.schema_transition_rejected_snapshot)
928            .saturating_add(self.schema_store_snapshots)
929            .saturating_add(self.schema_store_encoded_bytes)
930            .saturating_add(self.schema_store_latest_snapshot_bytes)
931            .saturating_add(self.accepted_schema_fields)
932            .saturating_add(self.accepted_schema_nested_leaf_facts)
933            .saturating_add(self.sql_compile_rejects)
934            .saturating_add(self.sql_compile_reject_cache_key)
935            .saturating_add(self.sql_compile_reject_parse)
936            .saturating_add(self.sql_compile_reject_semantic)
937            .saturating_add(self.plan_by_key)
938            .saturating_add(self.plan_by_keys)
939            .saturating_add(self.plan_key_range)
940            .saturating_add(self.plan_index_branch_set)
941            .saturating_add(self.plan_index_prefix)
942            .saturating_add(self.plan_index_multi_lookup)
943            .saturating_add(self.plan_index_range)
944            .saturating_add(self.plan_explicit_full_scan)
945            .saturating_add(self.plan_union)
946            .saturating_add(self.plan_intersection)
947            .saturating_add(self.plan_grouped_hash_materialized)
948            .saturating_add(self.plan_grouped_ordered_streaming)
949            .saturating_add(self.plan_choice_conflicting_primary_key_children_access_preferred)
950            .saturating_add(self.plan_choice_constant_false_predicate)
951            .saturating_add(self.plan_choice_empty_child_access_preferred)
952            .saturating_add(self.plan_choice_full_scan_access)
953            .saturating_add(self.plan_choice_intent_key_access_override)
954            .saturating_add(self.plan_choice_limit_zero_window)
955            .saturating_add(self.plan_choice_non_index_access)
956            .saturating_add(self.plan_choice_planner_composite_non_index)
957            .saturating_add(self.plan_choice_planner_full_scan_fallback)
958            .saturating_add(self.plan_choice_planner_key_set_access)
959            .saturating_add(self.plan_choice_planner_primary_key_lookup)
960            .saturating_add(self.plan_choice_planner_primary_key_range)
961            .saturating_add(self.plan_choice_required_order_primary_key_range_preferred)
962            .saturating_add(self.plan_choice_singleton_primary_key_child_access_preferred)
963            .saturating_add(self.prepared_shape_already_finalized)
964            .saturating_add(self.rows_loaded)
965            .saturating_add(self.rows_saved)
966            .saturating_add(self.rows_inserted)
967            .saturating_add(self.rows_updated)
968            .saturating_add(self.rows_replaced)
969            .saturating_add(self.rows_scanned)
970            .saturating_add(self.rows_filtered)
971            .saturating_add(self.rows_aggregated)
972            .saturating_add(self.rows_emitted)
973            .saturating_add(self.load_candidate_rows_scanned)
974            .saturating_add(self.load_candidate_rows_filtered)
975            .saturating_add(self.load_result_rows_emitted)
976            .saturating_add(self.rows_deleted)
977            .saturating_add(self.sql_insert_calls)
978            .saturating_add(self.sql_insert_select_calls)
979            .saturating_add(self.sql_update_calls)
980            .saturating_add(self.sql_delete_calls)
981            .saturating_add(self.sql_write_staged_rows)
982            .saturating_add(self.sql_write_matched_rows)
983            .saturating_add(self.sql_write_mutated_rows)
984            .saturating_add(self.sql_write_returning_rows)
985            .saturating_add(self.sql_write_error_insert)
986            .saturating_add(self.sql_write_error_insert_select)
987            .saturating_add(self.sql_write_error_update)
988            .saturating_add(self.sql_write_error_delete)
989            .saturating_add(self.sql_write_error_corruption)
990            .saturating_add(self.sql_write_error_incompatible_persisted_format)
991            .saturating_add(self.sql_write_error_not_found)
992            .saturating_add(self.sql_write_error_internal)
993            .saturating_add(self.sql_write_error_conflict)
994            .saturating_add(self.sql_write_error_unsupported)
995            .saturating_add(self.sql_write_error_invariant_violation)
996            .saturating_add(self.index_inserts)
997            .saturating_add(self.index_removes)
998            .saturating_add(self.reverse_index_inserts)
999            .saturating_add(self.reverse_index_removes)
1000            .saturating_add(self.relation_reverse_lookups)
1001            .saturating_add(self.relation_delete_blocks)
1002            .saturating_add(self.write_rows_touched)
1003            .saturating_add(self.write_index_entries_changed)
1004            .saturating_add(self.write_reverse_index_entries_changed)
1005            .saturating_add(self.write_relation_checks)
1006            .saturating_add(self.unique_violations)
1007            .saturating_add(self.non_atomic_partial_commits)
1008            .saturating_add(self.non_atomic_partial_rows_committed)
1009    }
1010}
1011
1012// Project mutable per-entity counters into the stable report DTO.
1013//
1014// Keeping this projection out of `report_window_start` leaves the window
1015// filtering logic readable while still making every report field explicit.
1016#[expect(clippy::too_many_lines)]
1017pub(in crate::metrics) fn entity_summary_from_counters(
1018    path: &str,
1019    ops: &EntityCounters,
1020) -> EntitySummary {
1021    EntitySummary {
1022        path: path.to_string(),
1023        load_calls: ops.load_calls,
1024        save_calls: ops.save_calls,
1025        delete_calls: ops.delete_calls,
1026        save_insert_calls: ops.save_insert_calls,
1027        save_update_calls: ops.save_update_calls,
1028        save_replace_calls: ops.save_replace_calls,
1029        exec_success: ops.exec_success,
1030        exec_error_corruption: ops.exec_error_corruption,
1031        exec_error_incompatible_persisted_format: ops.exec_error_incompatible_persisted_format,
1032        exec_error_not_found: ops.exec_error_not_found,
1033        exec_error_internal: ops.exec_error_internal,
1034        exec_error_conflict: ops.exec_error_conflict,
1035        exec_error_unsupported: ops.exec_error_unsupported,
1036        exec_error_invariant_violation: ops.exec_error_invariant_violation,
1037        exec_aborted: ops.exec_aborted,
1038        cache_shared_query_plan_hits: ops.cache_shared_query_plan_hits,
1039        cache_shared_query_plan_misses: ops.cache_shared_query_plan_misses,
1040        cache_shared_query_plan_inserts: ops.cache_shared_query_plan_inserts,
1041        cache_shared_query_plan_miss_cold: ops.cache_shared_query_plan_miss_cold,
1042        cache_shared_query_plan_miss_distinct_key: ops.cache_shared_query_plan_miss_distinct_key,
1043        cache_shared_query_plan_miss_schema_fingerprint: ops
1044            .cache_shared_query_plan_miss_schema_fingerprint,
1045        cache_shared_query_plan_miss_visibility: ops.cache_shared_query_plan_miss_visibility,
1046        cache_sql_compiled_command_hits: ops.cache_sql_compiled_command_hits,
1047        cache_sql_compiled_command_misses: ops.cache_sql_compiled_command_misses,
1048        cache_sql_compiled_command_inserts: ops.cache_sql_compiled_command_inserts,
1049        cache_sql_compiled_command_miss_cold: ops.cache_sql_compiled_command_miss_cold,
1050        cache_sql_compiled_command_miss_distinct_key: ops
1051            .cache_sql_compiled_command_miss_distinct_key,
1052        cache_sql_compiled_command_miss_schema_fingerprint: ops
1053            .cache_sql_compiled_command_miss_schema_fingerprint,
1054        cache_sql_compiled_command_miss_surface: ops.cache_sql_compiled_command_miss_surface,
1055        schema_reconcile_checks: ops.schema_reconcile_checks,
1056        schema_reconcile_exact_match: ops.schema_reconcile_exact_match,
1057        schema_reconcile_first_create: ops.schema_reconcile_first_create,
1058        schema_reconcile_latest_snapshot_corrupt: ops.schema_reconcile_latest_snapshot_corrupt,
1059        schema_reconcile_rejected_field_slot: ops.schema_reconcile_rejected_field_slot,
1060        schema_reconcile_rejected_other: ops.schema_reconcile_rejected_other,
1061        schema_reconcile_rejected_row_layout: ops.schema_reconcile_rejected_row_layout,
1062        schema_reconcile_rejected_schema_version: ops.schema_reconcile_rejected_schema_version,
1063        schema_reconcile_store_write_error: ops.schema_reconcile_store_write_error,
1064        schema_transition_checks: ops.schema_transition_checks,
1065        schema_transition_add_expression_index: ops.schema_transition_add_expression_index,
1066        schema_transition_add_field_path_index: ops.schema_transition_add_field_path_index,
1067        schema_transition_append_only_fields: ops.schema_transition_append_only_fields,
1068        schema_transition_constraint_activation: ops.schema_transition_constraint_activation,
1069        schema_transition_exact_match: ops.schema_transition_exact_match,
1070        schema_transition_metadata_only_field_default: ops
1071            .schema_transition_metadata_only_field_default,
1072        schema_transition_metadata_only_index_rename: ops
1073            .schema_transition_metadata_only_index_rename,
1074        schema_transition_rejected_entity_identity: ops.schema_transition_rejected_entity_identity,
1075        schema_transition_rejected_field_contract: ops.schema_transition_rejected_field_contract,
1076        schema_transition_rejected_field_slot: ops.schema_transition_rejected_field_slot,
1077        schema_transition_rejected_row_layout: ops.schema_transition_rejected_row_layout,
1078        schema_transition_rejected_schema_version: ops.schema_transition_rejected_schema_version,
1079        schema_transition_rejected_snapshot: ops.schema_transition_rejected_snapshot,
1080        schema_store_snapshots: ops.schema_store_snapshots,
1081        schema_store_encoded_bytes: ops.schema_store_encoded_bytes,
1082        schema_store_latest_snapshot_bytes: ops.schema_store_latest_snapshot_bytes,
1083        accepted_schema_fields: ops.accepted_schema_fields,
1084        accepted_schema_nested_leaf_facts: ops.accepted_schema_nested_leaf_facts,
1085        sql_compile_rejects: ops.sql_compile_rejects,
1086        sql_compile_reject_cache_key: ops.sql_compile_reject_cache_key,
1087        sql_compile_reject_parse: ops.sql_compile_reject_parse,
1088        sql_compile_reject_semantic: ops.sql_compile_reject_semantic,
1089        plan_by_key: ops.plan_by_key,
1090        plan_by_keys: ops.plan_by_keys,
1091        plan_key_range: ops.plan_key_range,
1092        plan_index_branch_set: ops.plan_index_branch_set,
1093        plan_index_prefix: ops.plan_index_prefix,
1094        plan_index_multi_lookup: ops.plan_index_multi_lookup,
1095        plan_index_range: ops.plan_index_range,
1096        plan_explicit_full_scan: ops.plan_explicit_full_scan,
1097        plan_union: ops.plan_union,
1098        plan_intersection: ops.plan_intersection,
1099        plan_grouped_hash_materialized: ops.plan_grouped_hash_materialized,
1100        plan_grouped_ordered_streaming: ops.plan_grouped_ordered_streaming,
1101        plan_choice_conflicting_primary_key_children_access_preferred: ops
1102            .plan_choice_conflicting_primary_key_children_access_preferred,
1103        plan_choice_constant_false_predicate: ops.plan_choice_constant_false_predicate,
1104        plan_choice_empty_child_access_preferred: ops.plan_choice_empty_child_access_preferred,
1105        plan_choice_full_scan_access: ops.plan_choice_full_scan_access,
1106        plan_choice_intent_key_access_override: ops.plan_choice_intent_key_access_override,
1107        plan_choice_limit_zero_window: ops.plan_choice_limit_zero_window,
1108        plan_choice_non_index_access: ops.plan_choice_non_index_access,
1109        plan_choice_planner_composite_non_index: ops.plan_choice_planner_composite_non_index,
1110        plan_choice_planner_full_scan_fallback: ops.plan_choice_planner_full_scan_fallback,
1111        plan_choice_planner_key_set_access: ops.plan_choice_planner_key_set_access,
1112        plan_choice_planner_primary_key_lookup: ops.plan_choice_planner_primary_key_lookup,
1113        plan_choice_planner_primary_key_range: ops.plan_choice_planner_primary_key_range,
1114        plan_choice_required_order_primary_key_range_preferred: ops
1115            .plan_choice_required_order_primary_key_range_preferred,
1116        plan_choice_singleton_primary_key_child_access_preferred: ops
1117            .plan_choice_singleton_primary_key_child_access_preferred,
1118        prepared_shape_already_finalized: ops.prepared_shape_already_finalized,
1119        rows_loaded: ops.rows_loaded,
1120        rows_saved: ops.rows_saved,
1121        rows_inserted: ops.rows_inserted,
1122        rows_updated: ops.rows_updated,
1123        rows_replaced: ops.rows_replaced,
1124        rows_scanned: ops.rows_scanned,
1125        rows_filtered: ops.rows_filtered,
1126        rows_aggregated: ops.rows_aggregated,
1127        rows_emitted: ops.rows_emitted,
1128        load_candidate_rows_scanned: ops.load_candidate_rows_scanned,
1129        load_candidate_rows_filtered: ops.load_candidate_rows_filtered,
1130        load_result_rows_emitted: ops.load_result_rows_emitted,
1131        rows_deleted: ops.rows_deleted,
1132        sql_insert_calls: ops.sql_insert_calls,
1133        sql_insert_select_calls: ops.sql_insert_select_calls,
1134        sql_update_calls: ops.sql_update_calls,
1135        sql_delete_calls: ops.sql_delete_calls,
1136        sql_write_staged_rows: ops.sql_write_staged_rows,
1137        sql_write_matched_rows: ops.sql_write_matched_rows,
1138        sql_write_mutated_rows: ops.sql_write_mutated_rows,
1139        sql_write_returning_rows: ops.sql_write_returning_rows,
1140        sql_write_error_insert: ops.sql_write_error_insert,
1141        sql_write_error_insert_select: ops.sql_write_error_insert_select,
1142        sql_write_error_update: ops.sql_write_error_update,
1143        sql_write_error_delete: ops.sql_write_error_delete,
1144        sql_write_error_corruption: ops.sql_write_error_corruption,
1145        sql_write_error_incompatible_persisted_format: ops
1146            .sql_write_error_incompatible_persisted_format,
1147        sql_write_error_not_found: ops.sql_write_error_not_found,
1148        sql_write_error_internal: ops.sql_write_error_internal,
1149        sql_write_error_conflict: ops.sql_write_error_conflict,
1150        sql_write_error_unsupported: ops.sql_write_error_unsupported,
1151        sql_write_error_invariant_violation: ops.sql_write_error_invariant_violation,
1152        index_inserts: ops.index_inserts,
1153        index_removes: ops.index_removes,
1154        reverse_index_inserts: ops.reverse_index_inserts,
1155        reverse_index_removes: ops.reverse_index_removes,
1156        relation_reverse_lookups: ops.relation_reverse_lookups,
1157        relation_delete_blocks: ops.relation_delete_blocks,
1158        write_rows_touched: ops.write_rows_touched,
1159        write_index_entries_changed: ops.write_index_entries_changed,
1160        write_reverse_index_entries_changed: ops.write_reverse_index_entries_changed,
1161        write_relation_checks: ops.write_relation_checks,
1162        unique_violations: ops.unique_violations,
1163        non_atomic_partial_commits: ops.non_atomic_partial_commits,
1164        non_atomic_partial_rows_committed: ops.non_atomic_partial_rows_committed,
1165    }
1166}