Skip to main content

cranpose_core/slot/
debug.rs

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