1use crate::{declaration::AllocationDeclaration, key::StableKey, slot::MemoryManagerSlot};
2use std::sync::Arc;
3
4pub fn declaration_for_key<'a>(
7 declarations: &'a [AllocationDeclaration],
8 key: &str,
9) -> Option<&'a AllocationDeclaration> {
10 declarations
11 .iter()
12 .find(|declaration| declaration.stable_key.as_str() == key)
13}
14
15#[derive(Clone, Debug, Eq, PartialEq)]
31pub struct CommittedAllocations {
32 declarations: Arc<Vec<AllocationDeclaration>>,
33 generation: u64,
34}
35
36impl CommittedAllocations {
37 pub(crate) fn from_persisted(
38 mut declarations: Vec<AllocationDeclaration>,
39 generation: u64,
40 ) -> Self {
41 declarations
43 .retain(|declaration| !crate::is_ic_memory_stable_key(declaration.stable_key.as_str()));
44 Self {
45 declarations: Arc::new(declarations),
46 generation,
47 }
48 }
49
50 #[must_use]
52 pub const fn generation(&self) -> u64 {
53 self.generation
54 }
55
56 #[must_use]
58 pub fn declarations(&self) -> &[AllocationDeclaration] {
59 &self.declarations
60 }
61
62 #[must_use]
64 pub fn slot_for(&self, key: &StableKey) -> Option<&MemoryManagerSlot> {
65 declaration_for_key(self.declarations(), key.as_str()).map(AllocationDeclaration::slot)
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn persistence_confirmation_publishes_shared_application_authority() {
75 let declarations = vec![
76 AllocationDeclaration::memory_manager(crate::IC_MEMORY_LEDGER_STABLE_KEY, 0).unwrap(),
77 AllocationDeclaration::memory_manager("app.rows.v1", 100).unwrap(),
78 ];
79 let committed = CommittedAllocations::from_persisted(declarations, 2);
80 let shared = committed.clone();
81
82 assert_eq!(committed.declarations().len(), 1);
83 assert_eq!(shared, committed);
84 assert!(std::ptr::eq(
85 shared.declarations(),
86 committed.declarations()
87 ));
88 assert_eq!(
89 committed.declarations()[0].stable_key().as_str(),
90 "app.rows.v1"
91 );
92 assert_eq!(committed.generation(), 2);
93 assert_eq!(
94 committed
95 .slot_for(&StableKey::parse("app.rows.v1").unwrap())
96 .unwrap()
97 .id(),
98 100
99 );
100 assert!(
101 committed
102 .slot_for(&StableKey::parse(crate::IC_MEMORY_LEDGER_STABLE_KEY).unwrap())
103 .is_none()
104 );
105 }
106}