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