ic_memory/slot/
memory_manager.rs1use super::descriptor::{AllocationSlot, AllocationSlotDescriptor};
2use super::range_authority::MemoryManagerIdRange;
3
4pub const MEMORY_MANAGER_SUBSTRATE: &str = "ic-stable-structures.memory_manager";
6
7pub const MEMORY_MANAGER_DESCRIPTOR_VERSION: u32 = 1;
9
10pub const MEMORY_MANAGER_MIN_ID: u8 = 0;
12
13pub const MEMORY_MANAGER_MAX_ID: u8 = 254;
15
16pub const MEMORY_MANAGER_INVALID_ID: u8 = u8::MAX;
18
19pub const IC_MEMORY_STABLE_KEY_PREFIX: &str = "ic_memory.";
21
22pub const IC_MEMORY_AUTHORITY_OWNER: &str = "ic-memory";
24
25pub const IC_MEMORY_AUTHORITY_PURPOSE: &str = "ic-memory allocation-governance authority";
27
28pub const IC_MEMORY_LEDGER_STABLE_KEY: &str = "ic_memory.ledger.v1";
30
31pub const IC_MEMORY_LEDGER_LABEL: &str = "MemoryLayoutLedger";
33
34pub const MEMORY_MANAGER_LEDGER_ID: u8 = MEMORY_MANAGER_MIN_ID;
36
37pub const MEMORY_MANAGER_GOVERNANCE_MAX_ID: u8 = 9;
39
40#[must_use]
42pub fn is_ic_memory_stable_key(stable_key: &str) -> bool {
43 stable_key.starts_with(IC_MEMORY_STABLE_KEY_PREFIX)
44}
45
46#[must_use]
48pub const fn memory_manager_governance_range() -> MemoryManagerIdRange {
49 MemoryManagerIdRange {
50 start: MEMORY_MANAGER_MIN_ID,
51 end: MEMORY_MANAGER_GOVERNANCE_MAX_ID,
52 }
53}
54
55impl AllocationSlotDescriptor {
56 pub fn memory_manager(id: u8) -> Result<Self, MemoryManagerSlotError> {
61 validate_memory_manager_id(id)?;
62 Ok(Self::memory_manager_unchecked(id))
63 }
64
65 #[must_use]
67 pub(crate) fn memory_manager_unchecked(id: u8) -> Self {
68 Self {
69 slot: AllocationSlot::MemoryManagerId(id),
70 substrate: MEMORY_MANAGER_SUBSTRATE.to_string(),
71 descriptor_version: MEMORY_MANAGER_DESCRIPTOR_VERSION,
72 }
73 }
74
75 pub fn memory_manager_checked(id: u8) -> Result<Self, MemoryManagerSlotError> {
79 Self::memory_manager(id)
80 }
81
82 pub fn memory_manager_id(&self) -> Result<u8, MemoryManagerSlotError> {
87 if self.substrate != MEMORY_MANAGER_SUBSTRATE {
88 return Err(MemoryManagerSlotError::UnsupportedSubstrate {
89 substrate: self.substrate.clone(),
90 });
91 }
92 if self.descriptor_version != MEMORY_MANAGER_DESCRIPTOR_VERSION {
93 return Err(MemoryManagerSlotError::UnsupportedDescriptorVersion {
94 version: self.descriptor_version,
95 });
96 }
97
98 let AllocationSlot::MemoryManagerId(id) = self.slot else {
99 return Err(MemoryManagerSlotError::UnsupportedSlot);
100 };
101
102 validate_memory_manager_id(id)?;
103 Ok(id)
104 }
105}
106
107#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
112pub enum MemoryManagerSlotError {
113 #[error("allocation slot is not a MemoryManager virtual memory ID")]
115 UnsupportedSlot,
116 #[error("allocation slot substrate '{substrate}' is not supported as a MemoryManager slot")]
118 UnsupportedSubstrate {
119 substrate: String,
121 },
122 #[error("MemoryManager slot descriptor version {version} is unsupported")]
124 UnsupportedDescriptorVersion {
125 version: u32,
127 },
128 #[error("MemoryManager ID {id} is not a usable allocation slot")]
130 InvalidMemoryManagerId {
131 id: u8,
133 },
134}
135
136pub const fn validate_memory_manager_id(id: u8) -> Result<(), MemoryManagerSlotError> {
138 if id == MEMORY_MANAGER_INVALID_ID {
139 return Err(MemoryManagerSlotError::InvalidMemoryManagerId { id });
140 }
141 Ok(())
142}