use crate::{
cdk::structures::{DefaultMemoryImpl, memory::VirtualMemory},
storage::{
prelude::*,
stable::sharding::{
SHARDING_CORE, ShardKey, ShardingAssignmentRecord, ShardingAssignmentsData,
ShardingCore, ShardingRegistryData, ShardingRegistryEntryRecord,
},
},
};
pub struct ShardingRegistry;
impl ShardingRegistry {
pub(crate) fn with<F, R>(f: F) -> R
where
F: FnOnce(&ShardingCore<VirtualMemory<DefaultMemoryImpl>>) -> R,
{
SHARDING_CORE.with_borrow(f)
}
pub(crate) fn with_mut<F, R>(f: F) -> R
where
F: FnOnce(&mut ShardingCore<VirtualMemory<DefaultMemoryImpl>>) -> R,
{
SHARDING_CORE.with_borrow_mut(f)
}
#[cfg(test)]
pub(crate) fn clear() {
Self::with_mut(|core| {
core.registry.clear_new();
core.assignments.clear_new();
});
}
#[must_use]
pub(crate) fn slot_for_shard(pool: &str, shard: Principal) -> Option<u32> {
Self::with(|s| s.get_entry(&shard)).and_then(|entry| {
if entry.pool.as_ref() == pool && entry.has_assigned_slot() {
Some(entry.slot)
} else {
None
}
})
}
#[must_use]
pub(crate) fn partition_key_shard(pool: &str, partition_key: &str) -> Option<Principal> {
let key = ShardKey::try_new(pool, partition_key).ok()?;
Self::with(|s| s.get_assignment(&key))
}
#[must_use]
pub(crate) fn partition_keys_in_shard(pool: &str, shard: Principal) -> Vec<String> {
Self::export_assignments()
.entries
.into_iter()
.filter(|record| record.shard == shard && record.key.pool.as_ref() == pool)
.map(|record| record.key.partition_key.to_string())
.collect()
}
#[must_use]
pub(crate) fn entries_for_pool(pool: &str) -> Vec<ShardingRegistryEntryRecord> {
Self::export_registry()
.entries
.into_iter()
.filter(|record| record.entry.pool.as_ref() == pool)
.collect()
}
#[must_use]
pub(crate) fn assignments_for_pool(pool: &str) -> Vec<ShardingAssignmentRecord> {
Self::export_assignments()
.entries
.into_iter()
.filter(|record| record.key.pool.as_ref() == pool)
.collect()
}
#[must_use]
pub(crate) fn export_registry() -> ShardingRegistryData {
ShardingRegistryData {
entries: Self::with(ShardingCore::all_entries),
}
}
#[must_use]
pub(crate) fn export_assignments() -> ShardingAssignmentsData {
ShardingAssignmentsData {
entries: Self::with(ShardingCore::all_assignments),
}
}
}