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 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}