1use crate::{declaration::AllocationDeclaration, key::StableKey, slot::MemoryManagerSlot};
2use std::sync::Arc;
3
4#[derive(Clone, Debug, Eq, PartialEq)]
22pub struct ValidatedAllocations {
23 base_generation: u64,
25 declarations: Vec<AllocationDeclaration>,
27}
28
29impl ValidatedAllocations {
30 pub(crate) const fn new(
31 base_generation: u64,
32 declarations: Vec<AllocationDeclaration>,
33 ) -> Self {
34 Self {
35 base_generation,
36 declarations,
37 }
38 }
39
40 #[must_use]
42 pub const fn base_generation(&self) -> u64 {
43 self.base_generation
44 }
45
46 #[must_use]
48 pub fn declarations(&self) -> &[AllocationDeclaration] {
49 &self.declarations
50 }
51
52 pub(crate) fn confirm_persisted(mut self, generation: u64) -> CommittedAllocations {
53 self.declarations
56 .retain(|declaration| !crate::is_ic_memory_stable_key(declaration.stable_key.as_str()));
57 CommittedAllocations {
58 declarations: Arc::new(self.declarations),
59 generation,
60 }
61 }
62}
63
64pub fn declaration_for_key<'a>(
67 declarations: &'a [AllocationDeclaration],
68 key: &str,
69) -> Option<&'a AllocationDeclaration> {
70 declarations
71 .iter()
72 .find(|declaration| declaration.stable_key.as_str() == key)
73}
74
75#[derive(Clone, Debug, Eq, PartialEq)]
92pub struct CommittedAllocations {
93 declarations: Arc<Vec<AllocationDeclaration>>,
94 generation: u64,
95}
96
97impl CommittedAllocations {
98 #[must_use]
100 pub const fn generation(&self) -> u64 {
101 self.generation
102 }
103
104 #[must_use]
106 pub fn declarations(&self) -> &[AllocationDeclaration] {
107 &self.declarations
108 }
109
110 #[must_use]
112 pub fn slot_for(&self, key: &StableKey) -> Option<&MemoryManagerSlot> {
113 declaration_for_key(self.declarations(), key.as_str()).map(AllocationDeclaration::slot)
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120
121 #[test]
122 fn persistence_confirmation_publishes_shared_application_authority() {
123 let validated = ValidatedAllocations::new(
124 1,
125 vec![
126 AllocationDeclaration::memory_manager(crate::IC_MEMORY_LEDGER_STABLE_KEY, 0)
127 .unwrap(),
128 AllocationDeclaration::memory_manager("app.rows.v1", 100).unwrap(),
129 ],
130 );
131 let committed = validated.clone().confirm_persisted(2);
132 let shared = committed.clone();
133
134 assert_eq!(validated.declarations().len(), 2);
135 assert_eq!(committed.declarations().len(), 1);
136 assert_eq!(shared, committed);
137 assert!(std::ptr::eq(
138 shared.declarations(),
139 committed.declarations()
140 ));
141 assert_eq!(
142 committed.declarations()[0].stable_key().as_str(),
143 "app.rows.v1"
144 );
145 assert_eq!(committed.generation(), 2);
146 assert_eq!(
147 committed
148 .slot_for(&StableKey::parse("app.rows.v1").unwrap())
149 .unwrap()
150 .id(),
151 100
152 );
153 assert!(
154 committed
155 .slot_for(&StableKey::parse(crate::IC_MEMORY_LEDGER_STABLE_KEY).unwrap())
156 .is_none()
157 );
158 }
159}