use crate::db::data::{CanonicalRow, DataKey, RawDataKey, RawRow};
use canic_cdk::structures::{BTreeMap, DefaultMemoryImpl, memory::VirtualMemory};
pub struct DataStore {
map: BTreeMap<RawDataKey, RawRow, VirtualMemory<DefaultMemoryImpl>>,
secondary_covering_authoritative: bool,
secondary_existence_witness_authoritative: bool,
}
impl DataStore {
#[must_use]
pub fn init(memory: VirtualMemory<DefaultMemoryImpl>) -> Self {
Self {
map: BTreeMap::init(memory),
secondary_covering_authoritative: false,
secondary_existence_witness_authoritative: false,
}
}
pub(in crate::db) fn insert(&mut self, key: RawDataKey, row: CanonicalRow) -> Option<RawRow> {
let previous = self.map.insert(key, row.into_raw_row());
self.invalidate_secondary_covering_authority();
self.invalidate_secondary_existence_witness_authority();
previous
}
#[cfg(test)]
pub(crate) fn insert_raw_for_test(&mut self, key: RawDataKey, row: RawRow) -> Option<RawRow> {
let previous = self.map.insert(key, row);
self.invalidate_secondary_covering_authority();
self.invalidate_secondary_existence_witness_authority();
previous
}
pub fn remove(&mut self, key: &RawDataKey) -> Option<RawRow> {
let previous = self.map.remove(key);
self.invalidate_secondary_covering_authority();
self.invalidate_secondary_existence_witness_authority();
previous
}
pub fn get(&self, key: &RawDataKey) -> Option<RawRow> {
self.map.get(key)
}
#[must_use]
pub fn contains(&self, key: &RawDataKey) -> bool {
self.map.contains_key(key)
}
pub fn clear(&mut self) {
self.map.clear();
self.invalidate_secondary_covering_authority();
self.invalidate_secondary_existence_witness_authority();
}
#[must_use]
pub(in crate::db) const fn secondary_covering_authoritative(&self) -> bool {
self.secondary_covering_authoritative
}
pub(in crate::db) const fn mark_secondary_covering_authoritative(&mut self) {
self.secondary_covering_authoritative = true;
}
#[must_use]
pub(in crate::db) const fn secondary_existence_witness_authoritative(&self) -> bool {
self.secondary_existence_witness_authoritative
}
pub(in crate::db) const fn mark_secondary_existence_witness_authoritative(&mut self) {
self.secondary_existence_witness_authoritative = true;
}
pub fn memory_bytes(&self) -> u64 {
self.iter()
.map(|entry| DataKey::STORED_SIZE_BYTES + entry.value().len() as u64)
.sum()
}
const fn invalidate_secondary_covering_authority(&mut self) {
self.secondary_covering_authoritative = false;
}
const fn invalidate_secondary_existence_witness_authority(&mut self) {
self.secondary_existence_witness_authoritative = false;
}
}
impl std::ops::Deref for DataStore {
type Target = BTreeMap<RawDataKey, RawRow, VirtualMemory<DefaultMemoryImpl>>;
fn deref(&self) -> &Self::Target {
&self.map
}
}