use std::any::Any;
use std::any::TypeId;
use dashmap::DashMap;
use crate::arc_erase::ArcEraseDyn;
use crate::storage::handle::PagableStorageHandle;
pub struct SessionContext {
map: DashMap<TypeId, Box<dyn Any + Send + Sync>>,
}
impl Default for SessionContext {
fn default() -> Self {
Self {
map: DashMap::new(),
}
}
}
impl SessionContext {
pub fn new() -> Self {
Self::default()
}
pub fn get<T: Any + Send + Sync + Clone>(&self) -> Option<T> {
self.map
.get(&TypeId::of::<T>())
.and_then(|r| r.downcast_ref::<T>().cloned())
}
pub fn get_or_insert_with<T: Any + Send + Sync + Clone>(&self, f: impl FnOnce() -> T) -> T {
self.map
.entry(TypeId::of::<T>())
.or_insert_with(|| Box::new(f()))
.downcast_ref::<T>()
.cloned()
.expect("downcast can't fail, type must be T")
}
pub fn set<T: Any + Send + Sync>(&self, value: T) {
self.map.insert(TypeId::of::<T>(), Box::new(value));
}
}
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
pub struct PagableCursor {
pub byte_pos: usize,
pub arc_index: usize,
}
pub trait Pagable:
Send + Sync + PagableSerialize + for<'a> PagableDeserialize<'a> + 'static
{
}
impl<T: Send + Sync + PagableSerialize + for<'a> PagableDeserialize<'a> + 'static> Pagable for T {}
pub trait PagableSerialize {
fn pagable_serialize(&self, serializer: &mut dyn PagableSerializer) -> crate::Result<()>;
}
pub trait PagableEagerSerialize {
fn eager_pagable_serialize<S: PagableSerializer>(
&self,
serializer: &mut S,
) -> crate::Result<()>;
}
pub trait PagableDeserialize<'de>: Sized {
fn pagable_deserialize<D: PagableDeserializer<'de> + ?Sized>(
deserializer: &mut D,
) -> crate::Result<Self>;
}
pub trait PagableDeserializeOwned: for<'de> PagableDeserialize<'de> {}
impl<T> PagableDeserializeOwned for T where T: for<'de> PagableDeserialize<'de> {}
pub trait PagableBoxDeserialize<'de> {
fn deserialize_box<D: PagableDeserializer<'de> + ?Sized>(
deserializer: &mut D,
) -> crate::Result<Box<Self>>;
}
pub trait PagableEagerDeserialize<'de>: Sized {
fn eager_pagable_deserialize<D: PagableDeserializer<'de> + ?Sized>(
deserializer: &mut D,
) -> crate::Result<Self>;
}
pub trait PagableSerializer {
fn serde(&mut self) -> &mut postcard::Serializer<crate::flavors::PagableVecFlavor>;
fn serialize_arc(&mut self, arc: &dyn ArcEraseDyn) -> crate::Result<()>;
fn position(&mut self) -> PagableCursor;
unsafe fn write_at(&mut self, pos: usize, bytes: &[u8]) {
self.serde().output.write_at(pos, bytes);
}
fn session_context(&mut self) -> &SessionContext;
}
static_assertions::assert_obj_safe!(PagableSerializer);
pub trait PagableDeserializer<'de> {
fn serde(&mut self) -> Box<dyn erased_serde::Deserializer<'de> + '_>;
fn position(&self) -> PagableCursor;
unsafe fn seek(&mut self, cursor: PagableCursor);
fn deserialize_arc(
&mut self,
type_id: std::any::TypeId,
deserialize_fn: for<'a> fn(
&mut dyn PagableDeserializer<'a>,
) -> crate::Result<Box<dyn ArcEraseDyn>>,
) -> crate::Result<Box<dyn ArcEraseDyn>>;
fn storage(&self) -> PagableStorageHandle;
fn as_dyn(&mut self) -> &mut dyn PagableDeserializer<'de>;
fn session_context(&self) -> &SessionContext;
}
static_assertions::assert_obj_safe!(PagableDeserializer<'_>);
impl<'de, D: PagableDeserializer<'de> + ?Sized> PagableDeserializer<'de> for &mut D {
fn serde(&mut self) -> Box<dyn erased_serde::Deserializer<'de> + '_> {
<D as PagableDeserializer<'de>>::serde(self)
}
fn deserialize_arc(
&mut self,
type_id: TypeId,
deserialize_fn: for<'a> fn(
&mut dyn PagableDeserializer<'a>,
) -> crate::Result<Box<dyn ArcEraseDyn>>,
) -> crate::Result<Box<dyn ArcEraseDyn>> {
<D as PagableDeserializer<'de>>::deserialize_arc(self, type_id, deserialize_fn)
}
fn position(&self) -> PagableCursor {
<D as PagableDeserializer<'de>>::position(self)
}
unsafe fn seek(&mut self, cursor: PagableCursor) {
unsafe { <D as PagableDeserializer<'de>>::seek(self, cursor) }
}
fn storage(&self) -> PagableStorageHandle {
<D as PagableDeserializer<'de>>::storage(self)
}
fn as_dyn(&mut self) -> &mut dyn PagableDeserializer<'de> {
self
}
fn session_context(&self) -> &SessionContext {
<D as PagableDeserializer<'de>>::session_context(self)
}
}
static_assertions::assert_impl_all!(dyn PagableDeserializer<'static>: PagableDeserializer<'static>);