use crate::{declaration::AllocationDeclaration, key::StableKey, slot::MemoryManagerSlot};
use std::sync::Arc;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ValidatedAllocations {
base_generation: u64,
declarations: Vec<AllocationDeclaration>,
}
impl ValidatedAllocations {
pub(crate) const fn new(
base_generation: u64,
declarations: Vec<AllocationDeclaration>,
) -> Self {
Self {
base_generation,
declarations,
}
}
#[must_use]
pub const fn base_generation(&self) -> u64 {
self.base_generation
}
#[must_use]
pub fn declarations(&self) -> &[AllocationDeclaration] {
&self.declarations
}
pub(crate) fn confirm_persisted(mut self, generation: u64) -> CommittedAllocations {
self.declarations
.retain(|declaration| !crate::is_ic_memory_stable_key(declaration.stable_key.as_str()));
CommittedAllocations {
declarations: Arc::new(self.declarations),
generation,
}
}
}
pub fn declaration_for_key<'a>(
declarations: &'a [AllocationDeclaration],
key: &str,
) -> Option<&'a AllocationDeclaration> {
declarations
.iter()
.find(|declaration| declaration.stable_key.as_str() == key)
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct CommittedAllocations {
declarations: Arc<Vec<AllocationDeclaration>>,
generation: u64,
}
impl CommittedAllocations {
#[must_use]
pub const fn generation(&self) -> u64 {
self.generation
}
#[must_use]
pub fn declarations(&self) -> &[AllocationDeclaration] {
&self.declarations
}
#[must_use]
pub fn slot_for(&self, key: &StableKey) -> Option<&MemoryManagerSlot> {
declaration_for_key(self.declarations(), key.as_str()).map(AllocationDeclaration::slot)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn persistence_confirmation_publishes_shared_application_authority() {
let validated = ValidatedAllocations::new(
1,
vec![
AllocationDeclaration::memory_manager(crate::IC_MEMORY_LEDGER_STABLE_KEY, 0)
.unwrap(),
AllocationDeclaration::memory_manager("app.rows.v1", 100).unwrap(),
],
);
let committed = validated.clone().confirm_persisted(2);
let shared = committed.clone();
assert_eq!(validated.declarations().len(), 2);
assert_eq!(committed.declarations().len(), 1);
assert_eq!(shared, committed);
assert!(std::ptr::eq(
shared.declarations(),
committed.declarations()
));
assert_eq!(
committed.declarations()[0].stable_key().as_str(),
"app.rows.v1"
);
assert_eq!(committed.generation(), 2);
assert_eq!(
committed
.slot_for(&StableKey::parse("app.rows.v1").unwrap())
.unwrap()
.id(),
100
);
assert!(
committed
.slot_for(&StableKey::parse(crate::IC_MEMORY_LEDGER_STABLE_KEY).unwrap())
.is_none()
);
}
}