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