use async_txn::{AsyncSpawner, BTreeCm};
pub use cheap_clone::CheapClone;
use super::*;
mod optimistic;
pub use optimistic::*;
#[allow(clippy::module_inception)]
mod serializable;
pub use serializable::*;
#[cfg(feature = "smol")]
#[cfg_attr(docsrs, doc(cfg(feature = "smol")))]
pub type SmolSerializableDb<K, V> = SerializableDb<K, V, SmolSpawner>;
#[cfg(feature = "tokio")]
#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
pub type TokioSerializableDb<K, V> = SerializableDb<K, V, TokioSpawner>;
#[cfg(feature = "async-std")]
#[cfg_attr(docsrs, doc(cfg(feature = "async-std")))]
pub type AsyncStdSerializableDb<K, V> = SerializableDb<K, V, AsyncStdSpawner>;
struct Inner<K, V, S>
where
S: AsyncSpawner,
{
tm: AsyncTm<K, V, BTreeCm<K>, BTreePwm<K, V>, S>,
map: SkipCore<K, V>,
}
impl<K, V, S: AsyncSpawner> Inner<K, V, S> {
async fn new(name: &str) -> Self {
let tm = AsyncTm::new(name, 0).await;
Self {
tm,
map: SkipCore::new(),
}
}
async fn version(&self) -> u64 {
self.tm.version().await
}
}
pub struct SerializableDb<K, V, S: AsyncSpawner> {
inner: Arc<Inner<K, V, S>>,
}
#[doc(hidden)]
impl<K, V, S: AsyncSpawner> AsSkipCore<K, V> for SerializableDb<K, V, S> {
#[inline]
#[allow(private_interfaces)]
fn as_inner(&self) -> &SkipCore<K, V> {
&self.inner.map
}
}
impl<K, V, S: AsyncSpawner> Clone for SerializableDb<K, V, S> {
#[inline]
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}
impl<K, V, S: AsyncSpawner> SerializableDb<K, V, S> {
#[inline]
pub async fn new() -> Self {
Self {
inner: Arc::new(Inner::new(core::any::type_name::<Self>()).await),
}
}
}
impl<K, V, S: AsyncSpawner> SerializableDb<K, V, S> {
#[inline]
pub async fn version(&self) -> u64 {
self.inner.version().await
}
#[inline]
pub async fn read(&self) -> ReadTransaction<K, V, SerializableDb<K, V, S>, BTreeCm<K>, S> {
ReadTransaction::new(self.clone(), self.inner.tm.read().await)
}
}
impl<K, V, S> SerializableDb<K, V, S>
where
K: CheapClone + Ord,
S: AsyncSpawner,
{
#[inline]
pub async fn optimistic_write(&self) -> OptimisticTransaction<K, V, S> {
OptimisticTransaction::new(self.clone()).await
}
#[inline]
pub async fn serializable_write(&self) -> SerializableTransaction<K, V, S> {
SerializableTransaction::new(self.clone()).await
}
}
impl<K, V, S> SerializableDb<K, V, S>
where
K: CheapClone + Ord + Send + 'static,
V: Send + 'static,
S: AsyncSpawner,
{
#[inline]
pub fn compact(&self) {
self.inner.map.compact(self.inner.tm.discard_hint());
}
}