1use crate::{AnchorId, Key, ScopeId};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
4pub struct SlotTableLocalDebugStats {
5 pub group_count: usize,
6 pub group_capacity: usize,
7 pub group_record_size: usize,
8 pub group_heap_bytes: usize,
9 pub payload_count: usize,
10 pub payload_capacity: usize,
11 pub active_payload_anchor_count: usize,
12 pub payload_anchor_slot_count: usize,
13 pub detached_payload_anchor_count: usize,
14 pub invalidated_payload_anchor_count: usize,
15 pub free_payload_anchor_count: usize,
16 pub payload_anchor_capacity: usize,
17 pub payload_anchor_heap_bytes: usize,
18 pub node_count: usize,
19 pub node_capacity: usize,
20 pub active_anchor_count: usize,
21 pub anchor_slot_count: usize,
22 pub anchor_sparse_count: usize,
23 pub detached_anchor_count: usize,
24 pub invalidated_anchor_count: usize,
25 pub free_anchor_count: usize,
26 pub anchor_capacity: usize,
27 pub anchor_heap_bytes: usize,
28 pub scope_index_count: usize,
29 pub scope_index_capacity: usize,
30 pub mutation: SlotTableMutationDebugStats,
31}
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
34pub(crate) struct SlotLifecycleDebugStats {
35 pub pending_drop_count: usize,
36 pub pending_drop_capacity: usize,
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
40pub struct SlotRetentionDebugStats {
41 pub retained_subtree_count: usize,
42 pub retained_group_count: usize,
43 pub retained_payload_count: usize,
44 pub retained_node_count: usize,
45 pub retained_scope_count: usize,
46 pub retained_anchor_count: usize,
47 pub retained_heap_bytes: usize,
48 pub retained_evictions_total: usize,
49}
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
52pub struct SlotTableDebugStats {
53 pub group_count: usize,
54 pub group_capacity: usize,
55 pub group_record_size: usize,
56 pub group_heap_bytes: usize,
57 pub payload_count: usize,
58 pub payload_capacity: usize,
59 pub active_payload_anchor_count: usize,
60 pub payload_anchor_slot_count: usize,
61 pub detached_payload_anchor_count: usize,
62 pub invalidated_payload_anchor_count: usize,
63 pub free_payload_anchor_count: usize,
64 pub payload_anchor_capacity: usize,
65 pub payload_anchor_heap_bytes: usize,
66 pub node_count: usize,
67 pub node_capacity: usize,
68 pub pending_drop_count: usize,
69 pub pending_drop_capacity: usize,
70 pub active_anchor_count: usize,
71 pub anchor_slot_count: usize,
72 pub anchor_sparse_count: usize,
73 pub detached_anchor_count: usize,
74 pub invalidated_anchor_count: usize,
75 pub free_anchor_count: usize,
76 pub anchor_capacity: usize,
77 pub anchor_heap_bytes: usize,
78 pub scope_index_count: usize,
79 pub scope_index_capacity: usize,
80 pub retained_subtree_count: usize,
81 pub retained_group_count: usize,
82 pub retained_payload_count: usize,
83 pub retained_node_count: usize,
84 pub retained_scope_count: usize,
85 pub retained_anchor_count: usize,
86 pub retained_heap_bytes: usize,
87 pub retained_evictions_total: usize,
88 pub mutation: SlotTableMutationDebugStats,
89}
90
91impl SlotTableDebugStats {
92 pub(crate) fn from_parts(
93 local: SlotTableLocalDebugStats,
94 lifecycle: SlotLifecycleDebugStats,
95 retention: SlotRetentionDebugStats,
96 ) -> Self {
97 Self {
98 group_count: local.group_count,
99 group_capacity: local.group_capacity,
100 group_record_size: local.group_record_size,
101 group_heap_bytes: local.group_heap_bytes,
102 payload_count: local.payload_count,
103 payload_capacity: local.payload_capacity,
104 active_payload_anchor_count: local.active_payload_anchor_count,
105 payload_anchor_slot_count: local.payload_anchor_slot_count,
106 detached_payload_anchor_count: local.detached_payload_anchor_count,
107 invalidated_payload_anchor_count: local.invalidated_payload_anchor_count,
108 free_payload_anchor_count: local.free_payload_anchor_count,
109 payload_anchor_capacity: local.payload_anchor_capacity,
110 payload_anchor_heap_bytes: local.payload_anchor_heap_bytes,
111 node_count: local.node_count,
112 node_capacity: local.node_capacity,
113 pending_drop_count: lifecycle.pending_drop_count,
114 pending_drop_capacity: lifecycle.pending_drop_capacity,
115 active_anchor_count: local.active_anchor_count,
116 anchor_slot_count: local.anchor_slot_count,
117 anchor_sparse_count: local.anchor_sparse_count,
118 detached_anchor_count: local.detached_anchor_count,
119 invalidated_anchor_count: local.invalidated_anchor_count,
120 free_anchor_count: local.free_anchor_count,
121 anchor_capacity: local.anchor_capacity,
122 anchor_heap_bytes: local.anchor_heap_bytes,
123 scope_index_count: local.scope_index_count,
124 scope_index_capacity: local.scope_index_capacity,
125 retained_subtree_count: retention.retained_subtree_count,
126 retained_group_count: retention.retained_group_count,
127 retained_payload_count: retention.retained_payload_count,
128 retained_node_count: retention.retained_node_count,
129 retained_scope_count: retention.retained_scope_count,
130 retained_anchor_count: retention.retained_anchor_count,
131 retained_heap_bytes: retention.retained_heap_bytes,
132 retained_evictions_total: retention.retained_evictions_total,
133 mutation: local.mutation,
134 }
135 }
136}
137
138#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
139pub struct SlotTableMutationDebugStats {
140 pub subtree_move_count: usize,
141 pub moved_group_count: usize,
142 pub moved_group_max_span: usize,
143 pub moved_payload_count: usize,
144 pub moved_payload_max_span: usize,
145 pub moved_node_count: usize,
146 pub moved_node_max_span: usize,
147 pub payload_location_range_refresh_count: usize,
148 pub payload_location_range_refresh_group_count: usize,
149 pub payload_location_range_refresh_group_max_span: usize,
150 pub payload_location_range_refresh_payload_count: usize,
151 pub payload_location_range_refresh_payload_max_span: usize,
152 pub payload_location_refresh_count: usize,
153 pub payload_location_refresh_payload_count: usize,
154 pub payload_location_refresh_max_span: usize,
155 pub group_index_refresh_count: usize,
156 pub group_index_refresh_group_count: usize,
157 pub group_index_refresh_max_span: usize,
158 pub segment_range_update_count: usize,
159 pub segment_range_update_group_count: usize,
160 pub segment_range_update_max_span: usize,
161}
162
163#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
164pub(crate) struct SlotTableDiagnostics {
165 mutation: SlotTableMutationDebugStats,
166}
167
168impl SlotTableDiagnostics {
169 pub(crate) fn mutation(&self) -> SlotTableMutationDebugStats {
170 self.mutation
171 }
172
173 pub(crate) fn record_subtree_move(
174 &mut self,
175 group_span: usize,
176 payload_span: usize,
177 node_span: usize,
178 ) {
179 self.mutation
180 .record_subtree_move(group_span, payload_span, node_span);
181 }
182
183 pub(crate) fn record_payload_location_range_refresh(
184 &mut self,
185 group_span: usize,
186 payload_span: usize,
187 ) {
188 self.mutation
189 .record_payload_location_range_refresh(group_span, payload_span);
190 }
191
192 pub(crate) fn record_group_index_refresh(&mut self, group_span: usize) {
193 self.mutation.record_group_index_refresh(group_span);
194 }
195
196 pub(crate) fn record_payload_location_refresh(&mut self, payload_span: usize) {
197 self.mutation.record_payload_location_refresh(payload_span);
198 }
199
200 pub(crate) fn record_segment_range_update(&mut self, group_span: usize) {
201 self.mutation.record_segment_range_update(group_span);
202 }
203}
204
205impl SlotTableMutationDebugStats {
206 pub(crate) fn record_subtree_move(
207 &mut self,
208 group_span: usize,
209 payload_span: usize,
210 node_span: usize,
211 ) {
212 self.subtree_move_count = self.subtree_move_count.saturating_add(1);
213 self.moved_group_count = self.moved_group_count.saturating_add(group_span);
214 self.moved_group_max_span = self.moved_group_max_span.max(group_span);
215 self.moved_payload_count = self.moved_payload_count.saturating_add(payload_span);
216 self.moved_payload_max_span = self.moved_payload_max_span.max(payload_span);
217 self.moved_node_count = self.moved_node_count.saturating_add(node_span);
218 self.moved_node_max_span = self.moved_node_max_span.max(node_span);
219 }
220
221 pub(crate) fn record_payload_location_range_refresh(
222 &mut self,
223 group_span: usize,
224 payload_span: usize,
225 ) {
226 self.payload_location_range_refresh_count =
227 self.payload_location_range_refresh_count.saturating_add(1);
228 self.payload_location_range_refresh_group_count = self
229 .payload_location_range_refresh_group_count
230 .saturating_add(group_span);
231 self.payload_location_range_refresh_group_max_span = self
232 .payload_location_range_refresh_group_max_span
233 .max(group_span);
234 self.payload_location_range_refresh_payload_count = self
235 .payload_location_range_refresh_payload_count
236 .saturating_add(payload_span);
237 self.payload_location_range_refresh_payload_max_span = self
238 .payload_location_range_refresh_payload_max_span
239 .max(payload_span);
240 }
241
242 pub(crate) fn record_group_index_refresh(&mut self, group_span: usize) {
243 self.group_index_refresh_count = self.group_index_refresh_count.saturating_add(1);
244 self.group_index_refresh_group_count = self
245 .group_index_refresh_group_count
246 .saturating_add(group_span);
247 self.group_index_refresh_max_span = self.group_index_refresh_max_span.max(group_span);
248 }
249
250 pub(crate) fn record_payload_location_refresh(&mut self, payload_span: usize) {
251 self.payload_location_refresh_count = self.payload_location_refresh_count.saturating_add(1);
252 self.payload_location_refresh_payload_count = self
253 .payload_location_refresh_payload_count
254 .saturating_add(payload_span);
255 self.payload_location_refresh_max_span =
256 self.payload_location_refresh_max_span.max(payload_span);
257 }
258
259 pub(crate) fn record_segment_range_update(&mut self, group_span: usize) {
260 self.segment_range_update_count = self.segment_range_update_count.saturating_add(1);
261 self.segment_range_update_group_count = self
262 .segment_range_update_group_count
263 .saturating_add(group_span);
264 self.segment_range_update_max_span = self.segment_range_update_max_span.max(group_span);
265 }
266}
267
268#[derive(Debug, Clone, Copy, PartialEq, Eq)]
269pub enum SlotDebugEntryKind {
270 Group,
271 Payload,
272 Node,
273}
274
275#[derive(Debug, Clone, PartialEq, Eq)]
276pub struct SlotDebugEntry {
277 pub kind: SlotDebugEntryKind,
278 pub path: String,
279 pub line: String,
280}
281
282#[derive(Debug, Clone, PartialEq, Eq, Default)]
283pub struct SlotDebugSnapshot {
284 pub active_groups: Vec<SlotDebugGroup>,
285 pub anchors: Vec<SlotDebugAnchor>,
286 pub scopes: Vec<SlotDebugScope>,
287 pub active_payload_count: usize,
288 pub active_node_count: usize,
289 pub active_scope_count: usize,
290 pub scope_index_count: usize,
291 pub runtime_scope_registry_count: Option<usize>,
292 pub retained_subtree_count: usize,
293 pub retained_group_count: usize,
294 pub retained_payload_count: usize,
295 pub retained_node_count: usize,
296 pub retained_scope_count: usize,
297}
298
299#[derive(Debug, Clone, Copy, PartialEq, Eq)]
300pub struct SlotDebugGroup {
301 pub index: usize,
302 pub anchor: AnchorId,
303 pub parent_anchor: AnchorId,
304 pub static_key: Key,
305 pub explicit_key: Option<Key>,
306 pub ordinal: u32,
307 pub scope_id: Option<ScopeId>,
308 pub depth: u32,
309 pub subtree_len: u32,
310 pub payload_len: usize,
311 pub node_len: usize,
312 pub subtree_node_count: u32,
313}
314
315#[derive(Debug, Clone, Copy, PartialEq, Eq)]
316pub struct SlotDebugAnchor {
317 pub anchor: AnchorId,
318 pub group_index: usize,
319}
320
321#[derive(Debug, Clone, Copy, PartialEq, Eq)]
322pub struct SlotDebugScope {
323 pub scope_id: ScopeId,
324 pub anchor: AnchorId,
325 pub group_index: usize,
326}