Skip to main content

ic_memory/slot/
memory_manager.rs

1use super::descriptor::{AllocationSlot, AllocationSlotDescriptor};
2use super::range_authority::MemoryManagerIdRange;
3
4/// First usable `MemoryManager` virtual memory ID.
5pub const MEMORY_MANAGER_MIN_ID: u8 = 0;
6
7/// Last usable `MemoryManager` virtual memory ID.
8pub const MEMORY_MANAGER_MAX_ID: u8 = 254;
9
10/// `MemoryManager` unallocated-bucket sentinel. This is not a usable slot.
11pub const MEMORY_MANAGER_INVALID_ID: u8 = u8::MAX;
12
13/// Stable-key namespace prefix reserved for `ic-memory` allocation-governance infrastructure.
14pub const IC_MEMORY_STABLE_KEY_PREFIX: &str = "ic_memory.";
15
16/// Diagnostic owner label for `ic-memory` allocation-governance infrastructure.
17pub const IC_MEMORY_AUTHORITY_OWNER: &str = "ic-memory";
18
19/// Diagnostic purpose for the `ic-memory` allocation-governance authority range.
20pub const IC_MEMORY_AUTHORITY_PURPOSE: &str = "ic-memory allocation-governance authority";
21
22/// Stable key of the allocation ledger when backed by the current MemoryManager substrate.
23pub const IC_MEMORY_LEDGER_STABLE_KEY: &str = "ic_memory.ledger.v1";
24
25/// Diagnostic label of the allocation ledger when backed by the current MemoryManager substrate.
26pub const IC_MEMORY_LEDGER_LABEL: &str = "MemoryLayoutLedger";
27
28/// MemoryManager ID used by the allocation ledger in the current MemoryManager substrate.
29pub const MEMORY_MANAGER_LEDGER_ID: u8 = MEMORY_MANAGER_MIN_ID;
30
31/// Last MemoryManager ID reserved for `ic-memory` governance in the current substrate.
32pub const MEMORY_MANAGER_GOVERNANCE_MAX_ID: u8 = 9;
33
34/// Return true when `stable_key` belongs to the `ic-memory` namespace.
35#[must_use]
36pub fn is_ic_memory_stable_key(stable_key: &str) -> bool {
37    stable_key.starts_with(IC_MEMORY_STABLE_KEY_PREFIX)
38}
39
40/// MemoryManager range reserved for `ic-memory` governance in the current substrate.
41#[must_use]
42pub const fn memory_manager_governance_range() -> MemoryManagerIdRange {
43    MemoryManagerIdRange {
44        start: MEMORY_MANAGER_MIN_ID,
45        end: MEMORY_MANAGER_GOVERNANCE_MAX_ID,
46    }
47}
48
49impl AllocationSlotDescriptor {
50    /// Construct a descriptor for a usable `MemoryManager` virtual memory ID.
51    ///
52    /// ID 255 is the `ic-stable-structures` unallocated-bucket sentinel and is
53    /// rejected.
54    pub fn memory_manager(id: u8) -> Result<Self, MemoryManagerSlotError> {
55        validate_memory_manager_id(id)?;
56        Ok(Self::memory_manager_unchecked(id))
57    }
58
59    /// Construct a descriptor for a `MemoryManager` virtual memory ID without validating it.
60    #[must_use]
61    pub(crate) const fn memory_manager_unchecked(id: u8) -> Self {
62        Self {
63            slot: AllocationSlot::MemoryManagerId(id),
64        }
65    }
66
67    /// Return the usable `MemoryManager` virtual memory ID represented by this descriptor.
68    ///
69    /// This validates sentinel ID rules before returning the numeric ID.
70    pub fn memory_manager_id(&self) -> Result<u8, MemoryManagerSlotError> {
71        let AllocationSlot::MemoryManagerId(id) = self.slot;
72        validate_memory_manager_id(id)?;
73        Ok(id)
74    }
75}
76
77///
78/// MemoryManagerSlotError
79///
80/// Invalid `MemoryManager` allocation slot descriptor.
81#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
82pub enum MemoryManagerSlotError {
83    /// ID 255 is the unallocated-bucket sentinel.
84    #[error("MemoryManager ID {id} is not a usable allocation slot")]
85    InvalidMemoryManagerId {
86        /// Invalid MemoryManager ID.
87        id: u8,
88    },
89}
90
91/// Validate that a `MemoryManager` ID is usable as an allocation slot.
92pub const fn validate_memory_manager_id(id: u8) -> Result<(), MemoryManagerSlotError> {
93    if id == MEMORY_MANAGER_INVALID_ID {
94        return Err(MemoryManagerSlotError::InvalidMemoryManagerId { id });
95    }
96    Ok(())
97}