1use crate::{AnchorId, Key, ScopeId};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
6pub struct SlotTableLocalDebugStats {
7 pub group_count: usize,
9 pub group_capacity: usize,
11 pub group_record_size: usize,
13 pub group_heap_bytes: usize,
15 pub payload_count: usize,
17 pub payload_capacity: usize,
19 pub active_payload_anchor_count: usize,
21 pub payload_anchor_slot_count: usize,
23 pub detached_payload_anchor_count: usize,
25 pub invalidated_payload_anchor_count: usize,
27 pub free_payload_anchor_count: usize,
29 pub payload_anchor_capacity: usize,
31 pub payload_anchor_heap_bytes: usize,
33 pub node_count: usize,
35 pub node_capacity: usize,
37 pub active_anchor_count: usize,
39 pub anchor_slot_count: usize,
41 pub anchor_sparse_count: usize,
43 pub detached_anchor_count: usize,
45 pub invalidated_anchor_count: usize,
47 pub free_anchor_count: usize,
49 pub anchor_capacity: usize,
51 pub anchor_heap_bytes: usize,
53 pub mutation: SlotTableMutationDebugStats,
55}
56
57#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
58pub(crate) struct SlotLifecycleDebugStats {
59 pub pending_drop_count: usize,
60 pub pending_drop_capacity: usize,
61}
62
63#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
66pub struct SlotRetentionDebugStats {
67 pub retained_subtree_count: usize,
69 pub retained_group_count: usize,
71 pub retained_payload_count: usize,
73 pub retained_node_count: usize,
75 pub retained_scope_count: usize,
77 pub retained_anchor_count: usize,
79 pub retained_heap_bytes: usize,
81 pub retained_evictions_total: usize,
83}
84
85#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
89pub struct SlotTableDebugStats {
90 pub group_count: usize,
92 pub group_capacity: usize,
94 pub group_record_size: usize,
96 pub group_heap_bytes: usize,
98 pub payload_count: usize,
100 pub payload_capacity: usize,
102 pub active_payload_anchor_count: usize,
104 pub payload_anchor_slot_count: usize,
106 pub detached_payload_anchor_count: usize,
108 pub invalidated_payload_anchor_count: usize,
110 pub free_payload_anchor_count: usize,
112 pub payload_anchor_capacity: usize,
114 pub payload_anchor_heap_bytes: usize,
116 pub node_count: usize,
118 pub node_capacity: usize,
120 pub pending_drop_count: usize,
122 pub pending_drop_capacity: usize,
124 pub active_anchor_count: usize,
126 pub anchor_slot_count: usize,
128 pub anchor_sparse_count: usize,
130 pub detached_anchor_count: usize,
132 pub invalidated_anchor_count: usize,
134 pub free_anchor_count: usize,
136 pub anchor_capacity: usize,
138 pub anchor_heap_bytes: usize,
140 pub retained_subtree_count: usize,
142 pub retained_group_count: usize,
144 pub retained_payload_count: usize,
146 pub retained_node_count: usize,
148 pub retained_scope_count: usize,
150 pub retained_anchor_count: usize,
152 pub retained_heap_bytes: usize,
154 pub retained_evictions_total: usize,
156 pub mutation: SlotTableMutationDebugStats,
158}
159
160impl SlotTableDebugStats {
161 pub(crate) fn from_parts(
162 local: SlotTableLocalDebugStats,
163 lifecycle: SlotLifecycleDebugStats,
164 retention: SlotRetentionDebugStats,
165 ) -> Self {
166 Self {
167 group_count: local.group_count,
168 group_capacity: local.group_capacity,
169 group_record_size: local.group_record_size,
170 group_heap_bytes: local.group_heap_bytes,
171 payload_count: local.payload_count,
172 payload_capacity: local.payload_capacity,
173 active_payload_anchor_count: local.active_payload_anchor_count,
174 payload_anchor_slot_count: local.payload_anchor_slot_count,
175 detached_payload_anchor_count: local.detached_payload_anchor_count,
176 invalidated_payload_anchor_count: local.invalidated_payload_anchor_count,
177 free_payload_anchor_count: local.free_payload_anchor_count,
178 payload_anchor_capacity: local.payload_anchor_capacity,
179 payload_anchor_heap_bytes: local.payload_anchor_heap_bytes,
180 node_count: local.node_count,
181 node_capacity: local.node_capacity,
182 pending_drop_count: lifecycle.pending_drop_count,
183 pending_drop_capacity: lifecycle.pending_drop_capacity,
184 active_anchor_count: local.active_anchor_count,
185 anchor_slot_count: local.anchor_slot_count,
186 anchor_sparse_count: local.anchor_sparse_count,
187 detached_anchor_count: local.detached_anchor_count,
188 invalidated_anchor_count: local.invalidated_anchor_count,
189 free_anchor_count: local.free_anchor_count,
190 anchor_capacity: local.anchor_capacity,
191 anchor_heap_bytes: local.anchor_heap_bytes,
192 retained_subtree_count: retention.retained_subtree_count,
193 retained_group_count: retention.retained_group_count,
194 retained_payload_count: retention.retained_payload_count,
195 retained_node_count: retention.retained_node_count,
196 retained_scope_count: retention.retained_scope_count,
197 retained_anchor_count: retention.retained_anchor_count,
198 retained_heap_bytes: retention.retained_heap_bytes,
199 retained_evictions_total: retention.retained_evictions_total,
200 mutation: local.mutation,
201 }
202 }
203}
204
205#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
209pub struct SlotTableMutationDebugStats {
210 pub subtree_move_count: usize,
212 pub moved_group_count: usize,
214 pub moved_group_max_span: usize,
216 pub moved_payload_count: usize,
218 pub moved_payload_max_span: usize,
220 pub moved_node_count: usize,
222 pub moved_node_max_span: usize,
224 pub payload_location_range_refresh_count: usize,
226 pub payload_location_range_refresh_group_count: usize,
228 pub payload_location_range_refresh_group_max_span: usize,
230 pub payload_location_range_refresh_payload_count: usize,
232 pub payload_location_range_refresh_payload_max_span: usize,
234 pub payload_location_refresh_count: usize,
236 pub payload_location_refresh_payload_count: usize,
238 pub payload_location_refresh_max_span: usize,
240 pub group_index_refresh_count: usize,
242 pub group_index_refresh_group_count: usize,
244 pub group_index_refresh_max_span: usize,
246 pub segment_range_update_count: usize,
248 pub segment_range_update_group_count: usize,
250 pub segment_range_update_max_span: usize,
252 pub payload_shift_bytes: usize,
255}
256
257#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
258pub(crate) struct SlotTableDiagnostics {
259 mutation: SlotTableMutationDebugStats,
260}
261
262impl SlotTableDiagnostics {
263 pub(crate) fn mutation(&self) -> SlotTableMutationDebugStats {
264 self.mutation
265 }
266
267 pub(crate) fn record_subtree_move(
268 &mut self,
269 group_span: usize,
270 payload_span: usize,
271 node_span: usize,
272 ) {
273 self.mutation
274 .record_subtree_move(group_span, payload_span, node_span);
275 }
276
277 pub(crate) fn record_payload_location_range_refresh(
278 &mut self,
279 group_span: usize,
280 payload_span: usize,
281 ) {
282 self.mutation
283 .record_payload_location_range_refresh(group_span, payload_span);
284 }
285
286 pub(crate) fn record_group_index_refresh(&mut self, group_span: usize) {
287 self.mutation.record_group_index_refresh(group_span);
288 }
289
290 pub(crate) fn record_payload_location_refresh(&mut self, payload_span: usize) {
291 self.mutation.record_payload_location_refresh(payload_span);
292 }
293
294 pub(crate) fn record_segment_range_update(&mut self, group_span: usize) {
295 self.mutation.record_segment_range_update(group_span);
296 }
297}
298
299impl SlotTableMutationDebugStats {
300 pub(crate) fn record_subtree_move(
301 &mut self,
302 group_span: usize,
303 payload_span: usize,
304 node_span: usize,
305 ) {
306 self.subtree_move_count = self.subtree_move_count.saturating_add(1);
307 self.moved_group_count = self.moved_group_count.saturating_add(group_span);
308 self.moved_group_max_span = self.moved_group_max_span.max(group_span);
309 self.moved_payload_count = self.moved_payload_count.saturating_add(payload_span);
310 self.moved_payload_max_span = self.moved_payload_max_span.max(payload_span);
311 self.moved_node_count = self.moved_node_count.saturating_add(node_span);
312 self.moved_node_max_span = self.moved_node_max_span.max(node_span);
313 }
314
315 pub(crate) fn record_payload_location_range_refresh(
316 &mut self,
317 group_span: usize,
318 payload_span: usize,
319 ) {
320 self.payload_location_range_refresh_count =
321 self.payload_location_range_refresh_count.saturating_add(1);
322 self.payload_location_range_refresh_group_count = self
323 .payload_location_range_refresh_group_count
324 .saturating_add(group_span);
325 self.payload_location_range_refresh_group_max_span = self
326 .payload_location_range_refresh_group_max_span
327 .max(group_span);
328 self.payload_location_range_refresh_payload_count = self
329 .payload_location_range_refresh_payload_count
330 .saturating_add(payload_span);
331 self.payload_location_range_refresh_payload_max_span = self
332 .payload_location_range_refresh_payload_max_span
333 .max(payload_span);
334 }
335
336 pub(crate) fn record_group_index_refresh(&mut self, group_span: usize) {
337 self.group_index_refresh_count = self.group_index_refresh_count.saturating_add(1);
338 self.group_index_refresh_group_count = self
339 .group_index_refresh_group_count
340 .saturating_add(group_span);
341 self.group_index_refresh_max_span = self.group_index_refresh_max_span.max(group_span);
342 }
343
344 pub(crate) fn record_payload_location_refresh(&mut self, payload_span: usize) {
345 self.payload_location_refresh_count = self.payload_location_refresh_count.saturating_add(1);
346 self.payload_location_refresh_payload_count = self
347 .payload_location_refresh_payload_count
348 .saturating_add(payload_span);
349 self.payload_location_refresh_max_span =
350 self.payload_location_refresh_max_span.max(payload_span);
351 }
352
353 pub(crate) fn record_segment_range_update(&mut self, group_span: usize) {
354 self.segment_range_update_count = self.segment_range_update_count.saturating_add(1);
355 self.segment_range_update_group_count = self
356 .segment_range_update_group_count
357 .saturating_add(group_span);
358 self.segment_range_update_max_span = self.segment_range_update_max_span.max(group_span);
359 }
360}
361
362#[derive(Debug, Clone, Copy, PartialEq, Eq)]
364pub enum SlotDebugEntryKind {
365 Group,
367 Payload,
369 Node,
371}
372
373#[derive(Debug, Clone, PartialEq, Eq)]
375pub struct SlotDebugEntry {
376 pub kind: SlotDebugEntryKind,
378 pub path: String,
380 pub line: String,
382}
383
384#[derive(Debug, Clone, PartialEq, Eq, Default)]
386pub struct SlotDebugSnapshot {
387 pub active_groups: Vec<SlotDebugGroup>,
389 pub anchors: Vec<SlotDebugAnchor>,
391 pub scopes: Vec<SlotDebugScope>,
393 pub active_payload_count: usize,
395 pub active_node_count: usize,
397 pub active_scope_count: usize,
399 pub retained_subtree_count: usize,
401 pub retained_group_count: usize,
403 pub retained_payload_count: usize,
405 pub retained_node_count: usize,
407 pub retained_scope_count: usize,
409}
410
411#[derive(Debug, Clone, Copy, PartialEq, Eq)]
413pub struct SlotDebugGroup {
414 pub index: usize,
416 pub anchor: AnchorId,
418 pub parent_anchor: AnchorId,
420 pub static_key: Key,
422 pub explicit_key: Option<Key>,
424 pub ordinal: u32,
427 pub scope_id: Option<ScopeId>,
429 pub depth: u32,
431 pub subtree_len: u32,
433 pub payload_len: usize,
435 pub node_len: usize,
437 pub subtree_node_count: u32,
439}
440
441#[derive(Debug, Clone, Copy, PartialEq, Eq)]
443pub struct SlotDebugAnchor {
444 pub anchor: AnchorId,
446 pub group_index: usize,
448}
449
450#[derive(Debug, Clone, Copy, PartialEq, Eq)]
452pub struct SlotDebugScope {
453 pub scope_id: ScopeId,
455 pub anchor: AnchorId,
457 pub group_index: usize,
459}