use crate::db::{
data::DataStore,
index::{IndexState, IndexStore},
schema::SchemaStore,
};
use std::{cell::RefCell, thread::LocalKey};
#[derive(Clone, Copy, Debug)]
pub struct StoreHandle {
data: &'static LocalKey<RefCell<DataStore>>,
index: &'static LocalKey<RefCell<IndexStore>>,
schema: &'static LocalKey<RefCell<SchemaStore>>,
allocations: StoreAllocationIdentities,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct StoreAllocationIdentity {
memory_id: u8,
stable_key: &'static str,
}
impl StoreAllocationIdentity {
#[must_use]
pub const fn new(memory_id: u8, stable_key: &'static str) -> Self {
Self {
memory_id,
stable_key,
}
}
#[must_use]
pub const fn memory_id(self) -> u8 {
self.memory_id
}
#[must_use]
pub const fn stable_key(self) -> &'static str {
self.stable_key
}
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct StoreAllocationIdentities {
data: Option<StoreAllocationIdentity>,
index: Option<StoreAllocationIdentity>,
schema: Option<StoreAllocationIdentity>,
}
impl StoreAllocationIdentities {
#[must_use]
pub const fn absent() -> Self {
Self {
data: None,
index: None,
schema: None,
}
}
#[must_use]
pub const fn new(
data: StoreAllocationIdentity,
index: StoreAllocationIdentity,
schema: StoreAllocationIdentity,
) -> Self {
Self {
data: Some(data),
index: Some(index),
schema: Some(schema),
}
}
#[must_use]
pub const fn data(self) -> Option<StoreAllocationIdentity> {
self.data
}
#[must_use]
pub const fn index(self) -> Option<StoreAllocationIdentity> {
self.index
}
#[must_use]
pub const fn schema(self) -> Option<StoreAllocationIdentity> {
self.schema
}
}
impl StoreHandle {
#[must_use]
pub const fn new(
data: &'static LocalKey<RefCell<DataStore>>,
index: &'static LocalKey<RefCell<IndexStore>>,
schema: &'static LocalKey<RefCell<SchemaStore>>,
allocations: StoreAllocationIdentities,
) -> Self {
Self {
data,
index,
schema,
allocations,
}
}
pub fn with_data<R>(&self, f: impl FnOnce(&DataStore) -> R) -> R {
#[cfg(feature = "diagnostics")]
{
crate::db::physical_access::measure_physical_access_operation(|| {
self.data.with_borrow(f)
})
}
#[cfg(not(feature = "diagnostics"))]
{
self.data.with_borrow(f)
}
}
pub fn with_data_mut<R>(&self, f: impl FnOnce(&mut DataStore) -> R) -> R {
self.data.with_borrow_mut(f)
}
pub fn with_index<R>(&self, f: impl FnOnce(&IndexStore) -> R) -> R {
#[cfg(feature = "diagnostics")]
{
crate::db::physical_access::measure_physical_access_operation(|| {
self.index.with_borrow(f)
})
}
#[cfg(not(feature = "diagnostics"))]
{
self.index.with_borrow(f)
}
}
pub fn with_index_mut<R>(&self, f: impl FnOnce(&mut IndexStore) -> R) -> R {
self.index.with_borrow_mut(f)
}
pub fn with_schema<R>(&self, f: impl FnOnce(&SchemaStore) -> R) -> R {
self.schema.with_borrow(f)
}
pub fn with_schema_mut<R>(&self, f: impl FnOnce(&mut SchemaStore) -> R) -> R {
self.schema.with_borrow_mut(f)
}
#[must_use]
pub(in crate::db) fn index_state(&self) -> IndexState {
self.with_index(IndexStore::state)
}
#[must_use]
pub(in crate::db) fn data_is_heap_storage(&self) -> bool {
self.with_data(DataStore::is_heap_storage)
}
pub(in crate::db) fn mark_index_building(&self) {
self.with_index_mut(IndexStore::mark_building);
}
pub(in crate::db) fn mark_index_ready(&self) {
self.with_index_mut(IndexStore::mark_ready);
}
#[must_use]
pub const fn data_store(&self) -> &'static LocalKey<RefCell<DataStore>> {
self.data
}
#[must_use]
pub const fn index_store(&self) -> &'static LocalKey<RefCell<IndexStore>> {
self.index
}
#[must_use]
pub const fn schema_store(&self) -> &'static LocalKey<RefCell<SchemaStore>> {
self.schema
}
#[must_use]
pub const fn data_allocation(&self) -> Option<StoreAllocationIdentity> {
self.allocations.data()
}
#[must_use]
pub const fn index_allocation(&self) -> Option<StoreAllocationIdentity> {
self.allocations.index()
}
#[must_use]
pub const fn schema_allocation(&self) -> Option<StoreAllocationIdentity> {
self.allocations.schema()
}
}