Skip to content
Snippets Groups Projects
Commit d8734bda authored by Éloïs's avatar Éloïs
Browse files

[feat] kv_typed: add backend memory_singleton

parent 0c527cb3
No related branches found
No related tags found
1 merge request!1335Gva proto 2
......@@ -28,6 +28,15 @@ impl KeyAsBytes for () {
}
fn fill_bytes(&self, _: &mut [u8]) {}
}
impl KeyAsBytes for EmptyKey {
fn as_bytes<T, F: FnMut(&[u8]) -> T>(&self, mut f: F) -> T {
f(&[])
}
fn fill_bytes_size(&self) -> Option<usize> {
Some(0)
}
fn fill_bytes(&self, _: &mut [u8]) {}
}
impl ValueAsBytes for EmptyValue {
fn as_bytes<T, F: FnMut(&[u8]) -> Result<T, KvError>>(&self, mut f: F) -> Result<T, KvError> {
f(&[])
......
......@@ -20,6 +20,7 @@ pub mod leveldb;
#[cfg(feature = "lmdb_backend")]
pub mod lmdb;
pub mod memory;
pub mod memory_singleton;
#[cfg(feature = "mock")]
pub mod mock;
#[cfg(feature = "sled_backend")]
......
// Copyright (C) 2020 Éloïs SANCHEZ.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//! Memory backend for KV Typed,
use crate::*;
#[derive(Clone, Copy, Debug)]
pub struct MemSingleton;
#[derive(Clone, Copy, Debug, Default)]
pub struct MemSingletonConf {
phantom: PhantomData<()>,
}
type KeyBytes = IVec;
type ValueBytes = IVec;
impl Backend for MemSingleton {
const NAME: &'static str = "mem_singleton";
type Col = MemCol;
type Conf = MemSingletonConf;
fn open(_conf: &Self::Conf) -> KvResult<Self> {
Ok(MemSingleton)
}
fn open_col(&mut self, _conf: &Self::Conf, _col_name: &str) -> KvResult<Self::Col> {
Ok(MemCol(None))
}
}
#[derive(Debug, Default)]
pub struct MemBatch(Option<IVec>);
impl BackendBatch for MemBatch {
fn upsert(&mut self, _k: &[u8], v: &[u8]) {
self.0 = Some(v.into());
}
fn remove(&mut self, _k: &[u8]) {
self.0 = None;
}
}
#[derive(Clone, Debug)]
pub struct MemCol(Option<ValueBytes>);
impl BackendCol for MemCol {
type Batch = MemBatch;
type KeyBytes = KeyBytes;
type ValueBytes = ValueBytes;
type Iter = MemIter;
#[inline(always)]
fn new_batch() -> Self::Batch {
MemBatch::default()
}
#[inline(always)]
fn clear(&mut self) -> KvResult<()> {
self.0 = None;
Ok(())
}
#[inline(always)]
fn count(&self) -> KvResult<usize> {
if self.0.is_some() {
Ok(1)
} else {
Ok(0)
}
}
#[inline(always)]
fn get<K: Key, V: Value>(&self, _k: &K) -> KvResult<Option<V>> {
self.0
.as_ref()
.map(|bytes| V::from_bytes(bytes).map_err(|e| KvError::DeserError(format!("{}", e))))
.transpose()
}
#[inline(always)]
fn get_ref<K: Key, V: ValueZc, D, F: Fn(&V::Ref) -> KvResult<D>>(
&self,
_k: &K,
f: F,
) -> KvResult<Option<D>> {
self.0
.as_ref()
.map(|bytes| {
if let Some(layout_verified) =
zerocopy::LayoutVerified::<_, V::Ref>::new(bytes.as_ref())
{
f(&layout_verified)
} else {
Err(KvError::DeserError(
"Bytes are invalid length or alignment.".to_owned(),
))
}
})
.transpose()
}
#[inline(always)]
fn get_ref_slice<K: Key, V: ValueSliceZc, D, F: Fn(&[V::Elem]) -> KvResult<D>>(
&self,
_k: &K,
f: F,
) -> KvResult<Option<D>> {
self.0
.as_ref()
.map(|bytes| {
if let Some(layout_verified) =
zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(&bytes[V::prefix_len()..])
{
f(&layout_verified)
} else {
Err(KvError::DeserError(
"Bytes are invalid length or alignment.".to_owned(),
))
}
})
.transpose()
}
#[inline(always)]
fn delete<K: Key>(&mut self, _k: &K) -> KvResult<()> {
self.0 = None;
Ok(())
}
#[inline(always)]
fn put<K: Key, V: Value>(&mut self, _k: &K, value: &V) -> KvResult<()> {
value.as_bytes(|value_bytes| {
self.0 = Some(value_bytes.into());
Ok(())
})
}
#[inline(always)]
fn write_batch(&mut self, inner_batch: Self::Batch) -> KvResult<()> {
self.0 = inner_batch.0;
Ok(())
}
#[inline(always)]
fn iter<K: Key, V: Value>(&self, _: RangeBytes) -> Self::Iter {
MemIter(self.0.clone())
}
#[inline(always)]
fn save(&self) -> KvResult<()> {
Ok(())
}
}
pub struct MemIter(Option<ValueBytes>);
impl Debug for MemIter {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MemIter").field("0", &"???").finish()
}
}
impl Iterator for MemIter {
type Item = Result<(KeyBytes, ValueBytes), DynErr>;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.0.take().map(|v| Ok((KeyBytes::default(), v)))
}
}
impl ReversableIterator for MemIter {
#[inline(always)]
fn reverse(self) -> Self {
self
}
}
impl BackendIter<IVec, IVec> for MemIter {}
......@@ -27,6 +27,16 @@ impl ExplorableKey for () {
}
}
impl ExplorableKey for EmptyKey {
fn from_explorer_str(_: &str) -> Result<Self, StringErr> {
Ok(EmptyKey)
}
fn to_explorer_string(&self) -> KvResult<String> {
Ok(String::with_capacity(0))
}
}
impl ExplorableKey for String {
fn from_explorer_str(source: &str) -> Result<Self, StringErr> {
Ok(source.to_owned())
......
......@@ -14,7 +14,13 @@ impl FromBytes for () {
Ok(())
}
}
impl FromBytes for EmptyKey {
type Err = std::convert::Infallible;
fn from_bytes(_: &[u8]) -> Result<Self, Self::Err> {
Ok(EmptyKey)
}
}
impl FromBytes for EmptyValue {
type Err = std::convert::Infallible;
......
......@@ -60,3 +60,6 @@ impl<T> Key for T where
+ Sized
{
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct EmptyKey;
......@@ -60,6 +60,7 @@ pub mod prelude {
#[cfg(feature = "lmdb_backend")]
pub use crate::backend::lmdb::{Lmdb, LmdbConf};
pub use crate::backend::memory::{Mem, MemConf};
pub use crate::backend::memory_singleton::{MemSingleton, MemSingletonConf};
#[cfg(feature = "mock")]
pub use crate::backend::mock::{MockBackend, MockBackendCol, MockBackendIter};
#[cfg(feature = "sled_backend")]
......@@ -80,7 +81,7 @@ pub mod prelude {
pub use crate::iter::{
keys::KvIterKeys, values::KvIterValues, EntryIter, KvIter, ResultIter, ReversableIterator,
};
pub use crate::key::Key;
pub use crate::key::{EmptyKey, Key};
pub use crate::subscription::{NewSubscribers, Subscriber, Subscribers};
pub use crate::transactional_read::{TransactionalRead, TxColRo};
pub use crate::transactional_write::{DbTxCollectionRw, TransactionalWrite, TxColRw};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment