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