1use crate::db::{
7 diagnostics::MemoryAllocations,
8 index::IndexState,
9 registry::{
10 StoreAllocationIdentityCapability, StoreCommitParticipation, StoreDurability,
11 StoreRecoveryCapability, StoreRuntimeStorageCapabilities, StoreSchemaMetadataCapability,
12 },
13};
14
15use serde::Deserialize;
16
17#[cfg_attr(doc, doc = "StorageReport\n\nLive storage snapshot payload.")]
18#[derive(Clone, Debug, Default, Deserialize, serde::Serialize)]
19#[cfg_attr(not(target_family = "wasm"), derive(ic_wire::Wire))]
20pub struct StorageReport {
21 pub(crate) memory_allocations: Option<MemoryAllocations>,
22 pub(crate) storage_data: Vec<DataStoreSnapshot>,
23 pub(crate) storage_index: Vec<IndexStoreSnapshot>,
24 pub(crate) schema_storage: Vec<SchemaStoreSnapshot>,
25 pub(crate) entity_storage: Vec<EntitySnapshot>,
26 pub(crate) corrupted_keys: u64,
27 pub(crate) corrupted_entries: u64,
28}
29
30impl StorageReport {
31 #[must_use]
33 pub(super) const fn new(
34 storage_data: Vec<DataStoreSnapshot>,
35 storage_index: Vec<IndexStoreSnapshot>,
36 schema_storage: Vec<SchemaStoreSnapshot>,
37 entity_storage: Vec<EntitySnapshot>,
38 corrupted_keys: u64,
39 corrupted_entries: u64,
40 memory_allocations: Option<MemoryAllocations>,
41 ) -> Self {
42 Self {
43 memory_allocations,
44 storage_data,
45 storage_index,
46 schema_storage,
47 entity_storage,
48 corrupted_keys,
49 corrupted_entries,
50 }
51 }
52
53 #[must_use]
58 pub const fn memory_allocations(&self) -> Option<&MemoryAllocations> {
59 self.memory_allocations.as_ref()
60 }
61
62 #[must_use]
64 pub const fn storage_data(&self) -> &[DataStoreSnapshot] {
65 self.storage_data.as_slice()
66 }
67
68 #[must_use]
70 pub const fn storage_index(&self) -> &[IndexStoreSnapshot] {
71 self.storage_index.as_slice()
72 }
73
74 #[must_use]
76 pub const fn schema_storage(&self) -> &[SchemaStoreSnapshot] {
77 self.schema_storage.as_slice()
78 }
79
80 #[must_use]
82 pub const fn entity_storage(&self) -> &[EntitySnapshot] {
83 self.entity_storage.as_slice()
84 }
85
86 #[must_use]
88 pub const fn corrupted_keys(&self) -> u64 {
89 self.corrupted_keys
90 }
91
92 #[must_use]
94 pub const fn corrupted_entries(&self) -> u64 {
95 self.corrupted_entries
96 }
97}
98
99#[cfg_attr(doc, doc = "SchemaStoreSnapshot\n\nSchema-store diagnostic row.")]
100#[derive(Clone, Debug, Default, Deserialize, serde::Serialize)]
101#[cfg_attr(not(target_family = "wasm"), derive(ic_wire::Wire))]
102pub struct SchemaStoreSnapshot {
103 pub(crate) path: String,
104 pub(crate) storage: StoreSnapshotStorageMode,
105 pub(crate) allocation: StoreAllocationIdentityCapability,
106 pub(crate) durability: StoreDurability,
107 pub(crate) commit: StoreCommitParticipation,
108 pub(crate) recovery: StoreRecoveryCapability,
109 pub(crate) schema_metadata: StoreSchemaMetadataCapability,
110 pub(crate) memory_id: Option<u8>,
111 pub(crate) stable_key: Option<String>,
112 pub(crate) schema_version: Option<u32>,
113 pub(crate) schema_fingerprint_method_version: Option<u8>,
114 pub(crate) schema_fingerprint: Option<String>,
115 pub(crate) entity_count: u64,
116}
117
118#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, serde::Serialize)]
123#[cfg_attr(not(target_family = "wasm"), derive(ic_wire::Wire))]
124pub enum StoreSnapshotStorageMode {
125 Heap,
126 #[default]
127 Journaled,
128}
129
130impl StoreSnapshotStorageMode {
131 #[must_use]
133 pub const fn as_str(self) -> &'static str {
134 match self {
135 Self::Heap => "heap",
136 Self::Journaled => "journaled",
137 }
138 }
139}
140
141#[derive(Clone, Debug, Eq, PartialEq)]
142pub(super) struct StoreSnapshotAllocationIdentity {
143 memory_id: u8,
144 stable_key: String,
145}
146
147impl StoreSnapshotAllocationIdentity {
148 pub(super) const fn new(memory_id: u8, stable_key: String) -> Self {
149 Self {
150 memory_id,
151 stable_key,
152 }
153 }
154
155 const fn memory_id(&self) -> u8 {
156 self.memory_id
157 }
158}
159
160#[derive(Clone, Debug, Default, Eq, PartialEq)]
161pub(super) struct StoreSnapshotSchemaMetadata {
162 version: Option<u32>,
163 fingerprint_method_version: Option<u8>,
164 fingerprint: Option<String>,
165}
166
167impl StoreSnapshotSchemaMetadata {
168 pub(super) const fn absent() -> Self {
169 Self {
170 version: None,
171 fingerprint_method_version: None,
172 fingerprint: None,
173 }
174 }
175
176 pub(super) const fn new(
177 schema_version: u32,
178 schema_fingerprint_method_version: u8,
179 schema_fingerprint: String,
180 ) -> Self {
181 Self {
182 version: Some(schema_version),
183 fingerprint_method_version: Some(schema_fingerprint_method_version),
184 fingerprint: Some(schema_fingerprint),
185 }
186 }
187
188 const fn schema_version(&self) -> Option<u32> {
189 self.version
190 }
191
192 const fn schema_fingerprint_method_version(&self) -> Option<u8> {
193 self.fingerprint_method_version
194 }
195
196 fn schema_fingerprint(&self) -> Option<String> {
197 self.fingerprint.clone()
198 }
199}
200
201#[derive(Clone, Debug, Eq, PartialEq)]
202struct StoreRoleSnapshotFields {
203 path: String,
204 storage: StoreSnapshotStorageMode,
205 allocation: StoreAllocationIdentityCapability,
206 durability: StoreDurability,
207 commit: StoreCommitParticipation,
208 recovery: StoreRecoveryCapability,
209 schema_metadata: StoreSchemaMetadataCapability,
210 memory_id: Option<u8>,
211 stable_key: Option<String>,
212 schema_version: Option<u32>,
213 schema_fingerprint_method_version: Option<u8>,
214 schema_fingerprint: Option<String>,
215}
216
217impl StoreRoleSnapshotFields {
218 fn new(
219 path: String,
220 storage: StoreSnapshotStorageMode,
221 capabilities: StoreRuntimeStorageCapabilities,
222 allocation: Option<StoreSnapshotAllocationIdentity>,
223 schema_metadata: StoreSnapshotSchemaMetadata,
224 ) -> Self {
225 let (memory_id, stable_key) = match allocation {
226 Some(allocation) => (Some(allocation.memory_id()), Some(allocation.stable_key)),
227 None => (None, None),
228 };
229 Self {
230 path,
231 storage,
232 allocation: capabilities.allocation_identity(),
233 durability: capabilities.durability(),
234 commit: capabilities.commit_participation(),
235 recovery: capabilities.recovery(),
236 schema_metadata: capabilities.schema_metadata(),
237 memory_id,
238 stable_key,
239 schema_version: schema_metadata.schema_version(),
240 schema_fingerprint_method_version: schema_metadata.schema_fingerprint_method_version(),
241 schema_fingerprint: schema_metadata.schema_fingerprint(),
242 }
243 }
244}
245
246#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
247pub(super) struct IndexStoreSnapshotStats {
248 entries: u64,
249 user_entries: u64,
250 system_entries: u64,
251 memory_bytes: u64,
252 state: IndexState,
253}
254
255impl IndexStoreSnapshotStats {
256 pub(super) const fn new(
257 entries: u64,
258 user_entries: u64,
259 system_entries: u64,
260 memory_bytes: u64,
261 state: IndexState,
262 ) -> Self {
263 Self {
264 entries,
265 user_entries,
266 system_entries,
267 memory_bytes,
268 state,
269 }
270 }
271}
272
273impl SchemaStoreSnapshot {
274 #[must_use]
276 pub(super) fn new(
277 path: String,
278 storage: StoreSnapshotStorageMode,
279 capabilities: StoreRuntimeStorageCapabilities,
280 allocation: Option<StoreSnapshotAllocationIdentity>,
281 schema_metadata: StoreSnapshotSchemaMetadata,
282 entity_count: u64,
283 ) -> Self {
284 let fields =
285 StoreRoleSnapshotFields::new(path, storage, capabilities, allocation, schema_metadata);
286 Self {
287 path: fields.path,
288 storage: fields.storage,
289 allocation: fields.allocation,
290 durability: fields.durability,
291 commit: fields.commit,
292 recovery: fields.recovery,
293 schema_metadata: fields.schema_metadata,
294 memory_id: fields.memory_id,
295 stable_key: fields.stable_key,
296 schema_version: fields.schema_version,
297 schema_fingerprint_method_version: fields.schema_fingerprint_method_version,
298 schema_fingerprint: fields.schema_fingerprint,
299 entity_count,
300 }
301 }
302
303 #[must_use]
305 pub const fn path(&self) -> &str {
306 self.path.as_str()
307 }
308
309 #[must_use]
311 pub const fn storage(&self) -> StoreSnapshotStorageMode {
312 self.storage
313 }
314
315 #[must_use]
317 pub const fn allocation(&self) -> StoreAllocationIdentityCapability {
318 self.allocation
319 }
320
321 #[must_use]
323 pub const fn durability(&self) -> StoreDurability {
324 self.durability
325 }
326
327 #[must_use]
329 pub const fn commit(&self) -> StoreCommitParticipation {
330 self.commit
331 }
332
333 #[must_use]
335 pub const fn recovery(&self) -> StoreRecoveryCapability {
336 self.recovery
337 }
338
339 #[must_use]
341 pub const fn schema_metadata(&self) -> StoreSchemaMetadataCapability {
342 self.schema_metadata
343 }
344
345 #[must_use]
347 pub const fn memory_id(&self) -> Option<u8> {
348 self.memory_id
349 }
350
351 #[must_use]
353 pub const fn stable_key(&self) -> Option<&str> {
354 match &self.stable_key {
355 Some(value) => Some(value.as_str()),
356 None => None,
357 }
358 }
359
360 #[must_use]
362 pub const fn schema_version(&self) -> Option<u32> {
363 self.schema_version
364 }
365
366 #[must_use]
368 pub const fn schema_fingerprint_method_version(&self) -> Option<u8> {
369 self.schema_fingerprint_method_version
370 }
371
372 #[must_use]
374 pub const fn schema_fingerprint(&self) -> Option<&str> {
375 match &self.schema_fingerprint {
376 Some(value) => Some(value.as_str()),
377 None => None,
378 }
379 }
380
381 #[must_use]
383 pub const fn entity_count(&self) -> u64 {
384 self.entity_count
385 }
386}
387
388#[cfg_attr(doc, doc = "DataStoreSnapshot\n\nData-store snapshot row.")]
389#[derive(Clone, Debug, Default, Deserialize, serde::Serialize)]
390#[cfg_attr(not(target_family = "wasm"), derive(ic_wire::Wire))]
391pub struct DataStoreSnapshot {
392 pub(crate) path: String,
393 pub(crate) storage: StoreSnapshotStorageMode,
394 pub(crate) allocation: StoreAllocationIdentityCapability,
395 pub(crate) durability: StoreDurability,
396 pub(crate) commit: StoreCommitParticipation,
397 pub(crate) recovery: StoreRecoveryCapability,
398 pub(crate) schema_metadata: StoreSchemaMetadataCapability,
399 pub(crate) memory_id: Option<u8>,
400 pub(crate) stable_key: Option<String>,
401 pub(crate) schema_version: Option<u32>,
402 pub(crate) schema_fingerprint_method_version: Option<u8>,
403 pub(crate) schema_fingerprint: Option<String>,
404 pub(crate) entries: u64,
405 pub(crate) memory_bytes: u64,
406}
407
408impl DataStoreSnapshot {
409 #[must_use]
411 pub(super) fn new(
412 path: String,
413 storage: StoreSnapshotStorageMode,
414 capabilities: StoreRuntimeStorageCapabilities,
415 allocation: Option<StoreSnapshotAllocationIdentity>,
416 schema_metadata: StoreSnapshotSchemaMetadata,
417 entries: u64,
418 memory_bytes: u64,
419 ) -> Self {
420 let fields =
421 StoreRoleSnapshotFields::new(path, storage, capabilities, allocation, schema_metadata);
422 Self {
423 path: fields.path,
424 storage: fields.storage,
425 allocation: fields.allocation,
426 durability: fields.durability,
427 commit: fields.commit,
428 recovery: fields.recovery,
429 schema_metadata: fields.schema_metadata,
430 memory_id: fields.memory_id,
431 stable_key: fields.stable_key,
432 schema_version: fields.schema_version,
433 schema_fingerprint_method_version: fields.schema_fingerprint_method_version,
434 schema_fingerprint: fields.schema_fingerprint,
435 entries,
436 memory_bytes,
437 }
438 }
439
440 #[must_use]
442 pub const fn path(&self) -> &str {
443 self.path.as_str()
444 }
445
446 #[must_use]
448 pub const fn storage(&self) -> StoreSnapshotStorageMode {
449 self.storage
450 }
451
452 #[must_use]
454 pub const fn allocation(&self) -> StoreAllocationIdentityCapability {
455 self.allocation
456 }
457
458 #[must_use]
460 pub const fn durability(&self) -> StoreDurability {
461 self.durability
462 }
463
464 #[must_use]
466 pub const fn commit(&self) -> StoreCommitParticipation {
467 self.commit
468 }
469
470 #[must_use]
472 pub const fn recovery(&self) -> StoreRecoveryCapability {
473 self.recovery
474 }
475
476 #[must_use]
478 pub const fn schema_metadata(&self) -> StoreSchemaMetadataCapability {
479 self.schema_metadata
480 }
481
482 #[must_use]
484 pub const fn memory_id(&self) -> Option<u8> {
485 self.memory_id
486 }
487
488 #[must_use]
490 pub const fn stable_key(&self) -> Option<&str> {
491 match &self.stable_key {
492 Some(value) => Some(value.as_str()),
493 None => None,
494 }
495 }
496
497 #[must_use]
499 pub const fn schema_version(&self) -> Option<u32> {
500 self.schema_version
501 }
502
503 #[must_use]
505 pub const fn schema_fingerprint_method_version(&self) -> Option<u8> {
506 self.schema_fingerprint_method_version
507 }
508
509 #[must_use]
511 pub const fn schema_fingerprint(&self) -> Option<&str> {
512 match &self.schema_fingerprint {
513 Some(value) => Some(value.as_str()),
514 None => None,
515 }
516 }
517
518 #[must_use]
520 pub const fn entries(&self) -> u64 {
521 self.entries
522 }
523
524 #[must_use]
526 pub const fn memory_bytes(&self) -> u64 {
527 self.memory_bytes
528 }
529}
530
531#[cfg_attr(doc, doc = "IndexStoreSnapshot\n\nIndex-store snapshot row.")]
532#[derive(Clone, Debug, Default, Deserialize, serde::Serialize)]
533#[cfg_attr(not(target_family = "wasm"), derive(ic_wire::Wire))]
534pub struct IndexStoreSnapshot {
535 pub(crate) path: String,
536 pub(crate) storage: StoreSnapshotStorageMode,
537 pub(crate) allocation: StoreAllocationIdentityCapability,
538 pub(crate) durability: StoreDurability,
539 pub(crate) commit: StoreCommitParticipation,
540 pub(crate) recovery: StoreRecoveryCapability,
541 pub(crate) schema_metadata: StoreSchemaMetadataCapability,
542 pub(crate) memory_id: Option<u8>,
543 pub(crate) stable_key: Option<String>,
544 pub(crate) schema_version: Option<u32>,
545 pub(crate) schema_fingerprint_method_version: Option<u8>,
546 pub(crate) schema_fingerprint: Option<String>,
547 pub(crate) entries: u64,
548 pub(crate) user_entries: u64,
549 pub(crate) system_entries: u64,
550 pub(crate) memory_bytes: u64,
551 pub(crate) state: IndexState,
552}
553
554impl IndexStoreSnapshot {
555 #[must_use]
557 pub(super) fn new(
558 path: String,
559 storage: StoreSnapshotStorageMode,
560 capabilities: StoreRuntimeStorageCapabilities,
561 allocation: Option<StoreSnapshotAllocationIdentity>,
562 schema_metadata: StoreSnapshotSchemaMetadata,
563 stats: IndexStoreSnapshotStats,
564 ) -> Self {
565 let fields =
566 StoreRoleSnapshotFields::new(path, storage, capabilities, allocation, schema_metadata);
567 Self {
568 path: fields.path,
569 storage: fields.storage,
570 allocation: fields.allocation,
571 durability: fields.durability,
572 commit: fields.commit,
573 recovery: fields.recovery,
574 schema_metadata: fields.schema_metadata,
575 memory_id: fields.memory_id,
576 stable_key: fields.stable_key,
577 schema_version: fields.schema_version,
578 schema_fingerprint_method_version: fields.schema_fingerprint_method_version,
579 schema_fingerprint: fields.schema_fingerprint,
580 entries: stats.entries,
581 user_entries: stats.user_entries,
582 system_entries: stats.system_entries,
583 memory_bytes: stats.memory_bytes,
584 state: stats.state,
585 }
586 }
587
588 #[must_use]
590 pub const fn path(&self) -> &str {
591 self.path.as_str()
592 }
593
594 #[must_use]
596 pub const fn storage(&self) -> StoreSnapshotStorageMode {
597 self.storage
598 }
599
600 #[must_use]
602 pub const fn allocation(&self) -> StoreAllocationIdentityCapability {
603 self.allocation
604 }
605
606 #[must_use]
608 pub const fn durability(&self) -> StoreDurability {
609 self.durability
610 }
611
612 #[must_use]
614 pub const fn commit(&self) -> StoreCommitParticipation {
615 self.commit
616 }
617
618 #[must_use]
620 pub const fn recovery(&self) -> StoreRecoveryCapability {
621 self.recovery
622 }
623
624 #[must_use]
626 pub const fn schema_metadata(&self) -> StoreSchemaMetadataCapability {
627 self.schema_metadata
628 }
629
630 #[must_use]
632 pub const fn memory_id(&self) -> Option<u8> {
633 self.memory_id
634 }
635
636 #[must_use]
638 pub const fn stable_key(&self) -> Option<&str> {
639 match &self.stable_key {
640 Some(value) => Some(value.as_str()),
641 None => None,
642 }
643 }
644
645 #[must_use]
647 pub const fn schema_version(&self) -> Option<u32> {
648 self.schema_version
649 }
650
651 #[must_use]
653 pub const fn schema_fingerprint_method_version(&self) -> Option<u8> {
654 self.schema_fingerprint_method_version
655 }
656
657 #[must_use]
659 pub const fn schema_fingerprint(&self) -> Option<&str> {
660 match &self.schema_fingerprint {
661 Some(value) => Some(value.as_str()),
662 None => None,
663 }
664 }
665
666 #[must_use]
668 pub const fn entries(&self) -> u64 {
669 self.entries
670 }
671
672 #[must_use]
674 pub const fn user_entries(&self) -> u64 {
675 self.user_entries
676 }
677
678 #[must_use]
680 pub const fn system_entries(&self) -> u64 {
681 self.system_entries
682 }
683
684 #[must_use]
686 pub const fn memory_bytes(&self) -> u64 {
687 self.memory_bytes
688 }
689
690 #[must_use]
693 pub const fn state(&self) -> IndexState {
694 self.state
695 }
696}
697
698#[cfg_attr(doc, doc = "EntitySnapshot\n\nPer-entity storage snapshot row.")]
699#[derive(Clone, Debug, Default, Deserialize, serde::Serialize)]
700#[cfg_attr(not(target_family = "wasm"), derive(ic_wire::Wire))]
701pub struct EntitySnapshot {
702 pub(crate) store: String,
703
704 pub(crate) path: String,
705
706 pub(crate) entries: u64,
707
708 pub(crate) memory_bytes: u64,
709}
710
711impl EntitySnapshot {
712 #[must_use]
714 pub(super) const fn new(store: String, path: String, entries: u64, memory_bytes: u64) -> Self {
715 Self {
716 store,
717 path,
718 entries,
719 memory_bytes,
720 }
721 }
722
723 #[must_use]
725 pub const fn store(&self) -> &str {
726 self.store.as_str()
727 }
728
729 #[must_use]
731 pub const fn path(&self) -> &str {
732 self.path.as_str()
733 }
734
735 #[must_use]
737 pub const fn entries(&self) -> u64 {
738 self.entries
739 }
740
741 #[must_use]
743 pub const fn memory_bytes(&self) -> u64 {
744 self.memory_bytes
745 }
746}