1use crate::{declaration::AllocationDeclaration, key::StableKey, slot::MemoryManagerSlot};
2use std::sync::Arc;
3
4#[derive(Clone, Debug, Eq, PartialEq)]
22pub struct ValidatedAllocations {
23 inner: Arc<ValidatedState>,
24}
25
26#[derive(Clone, Debug, Eq, PartialEq)]
27struct ValidatedState {
28 base_generation: u64,
30 declarations: Vec<AllocationDeclaration>,
32}
33
34impl ValidatedAllocations {
35 pub(crate) fn new(base_generation: u64, declarations: Vec<AllocationDeclaration>) -> Self {
36 Self {
37 inner: Arc::new(ValidatedState {
38 base_generation,
39 declarations,
40 }),
41 }
42 }
43
44 #[must_use]
46 pub fn base_generation(&self) -> u64 {
47 self.inner.base_generation
48 }
49
50 #[must_use]
52 pub fn declarations(&self) -> &[AllocationDeclaration] {
53 &self.inner.declarations
54 }
55
56 #[must_use]
58 pub fn slot_for(&self, key: &StableKey) -> Option<&MemoryManagerSlot> {
59 declaration_for_key(self.declarations(), key.as_str()).map(AllocationDeclaration::slot)
60 }
61
62 pub(crate) const fn confirm_persisted(self, generation: u64) -> CommittedAllocations {
63 CommittedAllocations {
64 validated: self,
65 generation,
66 }
67 }
68}
69
70pub fn declaration_for_key<'a>(
73 declarations: &'a [AllocationDeclaration],
74 key: &str,
75) -> Option<&'a AllocationDeclaration> {
76 declarations
77 .iter()
78 .find(|declaration| declaration.stable_key.as_str() == key)
79}
80
81#[derive(Clone, Debug, Eq, PartialEq)]
98pub struct CommittedAllocations {
99 validated: ValidatedAllocations,
100 generation: u64,
101}
102
103impl CommittedAllocations {
104 #[must_use]
106 pub const fn generation(&self) -> u64 {
107 self.generation
108 }
109
110 #[must_use]
112 pub fn declarations(&self) -> &[AllocationDeclaration] {
113 self.validated.declarations()
114 }
115
116 #[must_use]
118 pub fn slot_for(&self, key: &StableKey) -> Option<&MemoryManagerSlot> {
119 self.validated.slot_for(key)
120 }
121
122 pub(crate) fn into_application_allocations(mut self) -> Self {
125 Arc::make_mut(&mut self.validated.inner)
126 .declarations
127 .retain(|declaration| !crate::is_ic_memory_stable_key(declaration.stable_key.as_str()));
128 self
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use super::*;
135
136 #[test]
137 fn filtering_governance_does_not_change_shared_capabilities() {
138 let validated = ValidatedAllocations::new(
139 1,
140 vec![
141 AllocationDeclaration::memory_manager(
142 crate::IC_MEMORY_LEDGER_STABLE_KEY,
143 0,
144 "ledger",
145 )
146 .unwrap(),
147 AllocationDeclaration::memory_manager("app.rows.v1", 100, "rows").unwrap(),
148 ],
149 );
150 let committed = validated.clone().confirm_persisted(2);
151 let filtered = committed.clone().into_application_allocations();
152
153 assert_eq!(validated.declarations().len(), 2);
154 assert_eq!(committed.declarations().len(), 2);
155 assert_eq!(filtered.declarations().len(), 1);
156 assert_eq!(
157 filtered.declarations()[0].stable_key().as_str(),
158 "app.rows.v1"
159 );
160 assert_eq!(filtered.generation(), committed.generation());
161 }
162}