use {
crate::{
core::{
self,
cache::{CacheRead, CacheWrite},
misc::range_ext::{OwnedRangeBounds, RangeBoundsExt},
primitive::prollytree::refimpl,
workspace::Workspace,
Commit,
},
error::Type as TypeError,
path::{SegmentResolve, SegmentUpdate},
Addr, Error, Key, Value,
},
std::fmt,
};
pub struct Map<'f>(Box<dyn InnerMap<'f> + 'f>);
impl<'f> Map<'f> {
pub fn new<C, W>(inner: core::Map<'f, C, W>) -> Self
where
C: CacheRead + CacheWrite,
W: Workspace,
{
Self(Box::new(inner))
}
pub fn batch(&self) -> BatchMap<'f> {
self.0.inner_batch()
}
pub async fn insert<K, V>(&mut self, key: K, value: V) -> Result<Addr, Error>
where
K: Into<Key>,
V: Into<Value>,
{
self.0.inner_insert(key.into(), value.into()).await
}
pub async fn get<K>(&self, key: K) -> Result<Option<Value>, Error>
where
K: Into<Key>,
{
self.0.inner_get(key.into()).await
}
pub async fn iter<R>(
&self,
range: R,
) -> Result<Box<dyn Iterator<Item = Result<(Key, Value), Error>>>, Error>
where
R: RangeBoundsExt<Key>,
{
self.0.inner_iter(range.into_bounds()).await
}
pub async fn commit(&self) -> Result<Addr, Error> {
self.0.inner_commit().await
}
}
#[async_trait::async_trait]
trait InnerMap<'f> {
fn inner_batch(&self) -> BatchMap<'f>;
async fn inner_insert(&self, key: Key, value: Value) -> Result<Addr, Error>;
async fn inner_get(&self, key: Key) -> Result<Option<Value>, Error>;
async fn inner_iter(
&self,
range: OwnedRangeBounds<Key>,
) -> Result<Box<dyn Iterator<Item = Result<(Key, Value), Error>>>, Error>;
async fn inner_commit(&self) -> Result<Addr, Error>;
}
#[async_trait::async_trait]
impl<'f, C, W> InnerMap<'f> for core::Map<'f, C, W>
where
C: CacheRead + CacheWrite,
W: Workspace,
{
fn inner_batch(&self) -> BatchMap<'f> {
let b = self.batch();
BatchMap::new(b)
}
async fn inner_insert(&self, key: Key, value: Value) -> Result<Addr, Error> {
self.insert(key, value).await
}
async fn inner_get(&self, key: Key) -> Result<Option<Value>, Error> {
self.get(key).await
}
async fn inner_iter(
&self,
range: OwnedRangeBounds<Key>,
) -> Result<Box<dyn Iterator<Item = Result<(Key, Value), Error>>>, Error> {
self.iter(range).await
}
async fn inner_commit(&self) -> Result<Addr, Error> {
self.commit().await
}
}
pub struct BatchMap<'f>(Box<dyn InnerBatchMap + 'f>);
impl<'f> BatchMap<'f> {
pub fn new<C, W>(inner_map: core::map::BatchMap<'f, C, W>) -> Self
where
C: CacheRead + CacheWrite,
W: Workspace,
{
Self(Box::new(inner_map))
}
pub fn clear(&mut self) {
self.0.inner_clear()
}
pub fn insert<K, V>(&mut self, key: K, value: V)
where
K: Into<Key>,
V: Into<Value>,
{
self.0.inner_insert(key.into(), value.into())
}
pub async fn get<K>(&self, key: K) -> Result<Option<Value>, Error>
where
K: Into<Key>,
{
self.0.inner_get(key.into()).await
}
pub async fn stage(&mut self) -> Result<Addr, Error> {
self.0.inner_stage().await
}
pub async fn commit(&mut self) -> Result<Addr, Error> {
self.0.inner_commit().await
}
}
#[async_trait::async_trait]
trait InnerBatchMap {
fn inner_clear(&mut self);
fn inner_insert(&mut self, key: Key, value: Value);
async fn inner_get(&self, key: Key) -> Result<Option<Value>, Error>;
async fn inner_stage(&mut self) -> Result<Addr, Error>;
async fn inner_commit(&mut self) -> Result<Addr, Error>;
}
#[async_trait::async_trait]
impl<'f, C, W> InnerBatchMap for core::map::BatchMap<'f, C, W>
where
C: CacheRead + CacheWrite,
W: Workspace,
{
fn inner_clear(&mut self) {
self.clear();
}
fn inner_insert(&mut self, key: Key, value: Value) {
self.insert(key, value);
}
async fn inner_get(&self, key: Key) -> Result<Option<Value>, Error> {
self.get(key).await
}
async fn inner_stage(&mut self) -> Result<Addr, Error> {
self.stage().await
}
async fn inner_commit(&mut self) -> Result<Addr, Error> {
self.commit().await
}
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct PathSegment {
pub key: Key,
}
impl PathSegment {
pub fn new<T: Into<Key>>(t: T) -> Self {
Self { key: t.into() }
}
}
impl fmt::Debug for PathSegment {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("Map(")?;
self.key.fmt(f)?;
f.write_str(")")
}
}
impl fmt::Display for PathSegment {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("Map(")?;
self.key.fmt(f)?;
f.write_str(")")
}
}
#[async_trait::async_trait]
impl<C> SegmentResolve<C> for PathSegment
where
C: CacheRead,
{
async fn resolve(&self, storage: &C, self_addr: Addr) -> Result<Option<Addr>, Error> {
let reader = refimpl::Read::new(storage, self_addr);
let value = match reader.get(&self.key).await? {
Some(v) => v,
None => return Ok(None),
};
let addr = match value {
Value::Addr(addr) => addr,
_ => {
return Err(Error::Type(TypeError::UnexpectedValueVariant {
at_segment: Some(self.key.to_string()),
at_addr: None,
}));
},
};
Ok(Some(addr))
}
}
#[async_trait::async_trait]
impl<C> SegmentUpdate<C> for PathSegment
where
C: CacheRead + CacheWrite,
{
async fn update(
&self,
storage: &C,
self_addr: Option<Addr>,
child_addr: Addr,
) -> Result<Addr, Error> {
if let Some(self_addr) = self_addr {
let kvs = vec![(
self.key.clone(),
refimpl::Change::Insert(Value::Addr(child_addr)),
)];
refimpl::Update::new(storage, self_addr).with_vec(kvs).await
} else {
let kvs = vec![(self.key.clone(), Value::Addr(child_addr))];
refimpl::Create::new(storage).with_vec(kvs).await
}
}
}
impl<T> From<T> for PathSegment
where
T: Into<Key>,
{
fn from(t: T) -> Self {
Self { key: t.into() }
}
}