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 slot_for_key(self.declarations(), key.as_str())
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 slot_for_key<'a>(
73 declarations: &'a [AllocationDeclaration],
74 key: &str,
75) -> Option<&'a MemoryManagerSlot> {
76 declarations
77 .iter()
78 .find(|declaration| declaration.stable_key.as_str() == key)
79 .map(|declaration| &declaration.slot)
80}
81
82#[derive(Clone, Debug, Eq, PartialEq)]
101pub struct CommittedAllocations {
102 validated: ValidatedAllocations,
103 generation: u64,
104}
105
106impl CommittedAllocations {
107 #[must_use]
109 pub const fn generation(&self) -> u64 {
110 self.generation
111 }
112
113 #[must_use]
115 pub fn declarations(&self) -> &[AllocationDeclaration] {
116 self.validated.declarations()
117 }
118
119 #[must_use]
121 pub fn slot_for(&self, key: &StableKey) -> Option<&MemoryManagerSlot> {
122 self.validated.slot_for(key)
123 }
124
125 pub(crate) fn into_application_allocations(mut self) -> Self {
128 Arc::make_mut(&mut self.validated.inner)
129 .declarations
130 .retain(|declaration| !crate::is_ic_memory_stable_key(declaration.stable_key.as_str()));
131 self
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138
139 #[test]
140 fn filtering_governance_does_not_change_shared_capabilities() {
141 let validated = ValidatedAllocations::new(
142 1,
143 vec![
144 AllocationDeclaration::memory_manager(
145 crate::IC_MEMORY_LEDGER_STABLE_KEY,
146 0,
147 "ledger",
148 )
149 .unwrap(),
150 AllocationDeclaration::memory_manager("app.rows.v1", 100, "rows").unwrap(),
151 ],
152 );
153 let committed = validated.clone().confirm_persisted(2);
154 let filtered = committed.clone().into_application_allocations();
155
156 assert_eq!(validated.declarations().len(), 2);
157 assert_eq!(committed.declarations().len(), 2);
158 assert_eq!(filtered.declarations().len(), 1);
159 assert_eq!(
160 filtered.declarations()[0].stable_key().as_str(),
161 "app.rows.v1"
162 );
163 assert_eq!(filtered.generation(), committed.generation());
164 }
165}