ic_memory/ledger/
record.rs1#[cfg(any(test, feature = "test-support"))]
2use super::LedgerIntegrityError;
3use crate::{declaration::AllocationDeclaration, key::StableKey, slot::MemoryManagerSlot};
4use serde::{Deserialize, Serialize};
5
6#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
18#[serde(deny_unknown_fields)]
19pub struct AllocationLedger {
20 pub(crate) current_generation: u64,
21 #[serde(deserialize_with = "crate::cbor::deserialize_records")]
22 pub(crate) records: Vec<AllocationRecord>,
23}
24
25#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
34#[serde(deny_unknown_fields)]
35pub struct AllocationRecord {
36 pub(crate) stable_key: StableKey,
37 pub(crate) slot: MemoryManagerSlot,
38}
39
40#[derive(Clone, Debug, Eq, PartialEq)]
50pub struct RecoveredLedger {
51 ledger: AllocationLedger,
52}
53
54impl RecoveredLedger {
55 pub(crate) fn genesis_for_absent_snapshot(error: &super::LedgerCommitError) -> Option<Self> {
58 matches!(
59 error,
60 super::LedgerCommitError::Recovery(crate::CommitRecoveryError::NoValidGeneration)
61 )
62 .then(|| Self::from_trusted_ledger(AllocationLedger::empty_genesis()))
63 }
64
65 pub(crate) const fn from_trusted_ledger(ledger: AllocationLedger) -> Self {
66 Self { ledger }
67 }
68
69 #[must_use]
71 pub const fn ledger(&self) -> &AllocationLedger {
72 &self.ledger
73 }
74
75 #[must_use]
77 #[cfg(test)]
78 pub const fn current_generation(&self) -> u64 {
79 self.ledger.current_generation
80 }
81
82 pub(crate) fn into_ledger(self) -> AllocationLedger {
83 self.ledger
84 }
85}
86
87impl AllocationRecord {
88 pub(crate) fn from_declaration(declaration: &AllocationDeclaration) -> Self {
89 Self {
90 stable_key: declaration.stable_key.clone(),
91 slot: declaration.slot.clone(),
92 }
93 }
94
95 #[must_use]
97 pub const fn stable_key(&self) -> &StableKey {
98 &self.stable_key
99 }
100
101 #[must_use]
103 pub const fn slot(&self) -> &MemoryManagerSlot {
104 &self.slot
105 }
106}
107
108impl AllocationLedger {
109 pub(crate) const fn empty_genesis() -> Self {
110 Self {
111 current_generation: 0,
112 records: Vec::new(),
113 }
114 }
115
116 #[cfg(any(test, feature = "test-support"))]
119 pub fn new(
120 current_generation: u64,
121 records: Vec<AllocationRecord>,
122 ) -> Result<Self, LedgerIntegrityError> {
123 let ledger = Self {
124 current_generation,
125 records,
126 };
127 ledger.validate_integrity()?;
128 Ok(ledger)
129 }
130
131 #[must_use]
133 pub const fn current_generation(&self) -> u64 {
134 self.current_generation
135 }
136
137 #[must_use]
139 pub fn records(&self) -> &[AllocationRecord] {
140 &self.records
141 }
142
143 pub(crate) fn occupied_slots(&self) -> [bool; crate::constants::MAX_ALLOCATIONS] {
145 let mut occupied = [false; crate::constants::MAX_ALLOCATIONS];
146 for record in &self.records {
147 occupied[usize::from(record.slot.id())] = true;
148 }
149 occupied
150 }
151}