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