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