Add get and put methods

This commit is contained in:
Olivier 'reivilibre' 2022-03-24 19:25:33 +00:00
parent b01fe7f892
commit 1622d45c23
4 changed files with 88 additions and 3 deletions

View File

@ -1,5 +1,8 @@
use libmdbx::{Database, Environment, WriteMap};
use crate::environment::Txn;
use crate::wrapper::ZeroCopyByteWrapper;
use libmdbx::{Database, Environment, TransactionKind, WriteFlags, WriteMap, RW};
use ouroboros::self_referencing;
use std::borrow::Cow;
use std::marker::PhantomData;
use std::sync::Arc;
@ -14,3 +17,35 @@ pub struct RawTable<K: ?Sized, V: ?Sized> {
pub(crate) phantom_k: PhantomData<K>,
pub(crate) phantom_v: PhantomData<V>,
}
impl<K: ?Sized + ZeroCopyByteWrapper, V: ?Sized + ZeroCopyByteWrapper> RawTable<K, V> {
pub fn get<'txn, TK: TransactionKind>(
&'txn self,
txn: &'txn Txn<'txn, TK>,
k: impl AsRef<K>,
) -> anyhow::Result<Option<Cow<'txn, V>>> {
let bytes = txn
.mdbx_txn
.get::<Cow<'txn, [u8]>>(self.borrow_mdbx_db(), k.as_ref().as_byte_slice())?;
Ok(match bytes {
None => None,
Some(Cow::Owned(owned)) => Some(Cow::Owned(V::from_owned_bytes(owned)?)),
Some(Cow::Borrowed(borrowed)) => Some(Cow::Borrowed(V::from_byte_slice(borrowed)?)),
})
}
pub fn put<'txn>(
&self,
txn: &Txn<'txn, RW>,
k: impl AsRef<K>,
v: impl AsRef<V>,
) -> anyhow::Result<()> {
txn.mdbx_txn.put(
self.borrow_mdbx_db(),
k.as_ref().as_byte_slice(),
v.as_ref().as_byte_slice(),
WriteFlags::empty(),
)?;
Ok(())
}
}

View File

@ -1,7 +1,48 @@
use crate::database::raw::RawTable;
use crate::environment::Txn;
use crate::wrapper::ByteWrapper;
use anyhow::Context;
use libmdbx::{TransactionKind, RW};
pub struct WrappedTable<K, V> {
pub raw: RawTable<[u8], [u8]>,
pub k_wrapper: K,
pub v_wrapper: V,
}
impl<K: ByteWrapper, V: ByteWrapper> WrappedTable<K, V> {
pub fn get<'txn, TK: TransactionKind>(
&self,
txn: &Txn<'txn, TK>,
k: impl AsRef<K::Item>,
) -> anyhow::Result<Option<V::Item>> {
let k_bytes = self
.k_wrapper
.dump_to_db_bytes(k.as_ref())
.context("whilst converting key to bytes")?;
self.raw
.get(txn, k_bytes)?
.map(|v_bytes| self.v_wrapper.load_from_db_bytes(&v_bytes))
.transpose()
}
pub fn put<'txn>(
&self,
txn: &Txn<'txn, RW>,
k: impl AsRef<K::Item>,
v: impl AsRef<V::Item>,
) -> anyhow::Result<()> {
let k_bytes = self
.k_wrapper
.dump_to_db_bytes(k.as_ref())
.context("whilst converting key to bytes")?;
let v_bytes = self
.v_wrapper
.dump_to_db_bytes(v.as_ref())
.context("whilst converting value to bytes")?;
self.raw.put(txn, k_bytes, v_bytes)?;
Ok(())
}
}

View File

@ -76,7 +76,7 @@ impl Env {
pub fn rw_txn<R>(&self, func: impl FnOnce(&Txn<RW>) -> anyhow::Result<R>) -> anyhow::Result<R> {
let txn = self.begin_rw_txn()?;
let result = func(&txn)?;
txn.commit()?;
txn.commit().context("Failed to commit")?;
Ok(result)
}
}

View File

@ -69,9 +69,10 @@ impl<T: ByteWrapper> ByteWrapper for Arc<T> {
}
}
pub trait ZeroCopyByteWrapper {
pub trait ZeroCopyByteWrapper: ToOwned {
fn as_byte_slice(&self) -> &[u8];
fn from_byte_slice(bytes: &[u8]) -> anyhow::Result<&Self>;
fn from_owned_bytes(bytes: Vec<u8>) -> anyhow::Result<Self::Owned>;
}
impl ZeroCopyByteWrapper for [u8] {
@ -82,6 +83,10 @@ impl ZeroCopyByteWrapper for [u8] {
fn from_byte_slice(bytes: &[u8]) -> anyhow::Result<&Self> {
Ok(bytes)
}
fn from_owned_bytes(bytes: Vec<u8>) -> anyhow::Result<Self::Owned> {
Ok(bytes)
}
}
impl ZeroCopyByteWrapper for str {
@ -92,4 +97,8 @@ impl ZeroCopyByteWrapper for str {
fn from_byte_slice(bytes: &[u8]) -> anyhow::Result<&Self> {
Ok(std::str::from_utf8(bytes)?)
}
fn from_owned_bytes(bytes: Vec<u8>) -> anyhow::Result<Self::Owned> {
Ok(String::from_utf8(bytes)?)
}
}