Add get and put methods
This commit is contained in:
parent
b01fe7f892
commit
1622d45c23
@ -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 ouroboros::self_referencing;
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -14,3 +17,35 @@ pub struct RawTable<K: ?Sized, V: ?Sized> {
|
|||||||
pub(crate) phantom_k: PhantomData<K>,
|
pub(crate) phantom_k: PhantomData<K>,
|
||||||
pub(crate) phantom_v: PhantomData<V>,
|
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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,48 @@
|
|||||||
use crate::database::raw::RawTable;
|
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 struct WrappedTable<K, V> {
|
||||||
pub raw: RawTable<[u8], [u8]>,
|
pub raw: RawTable<[u8], [u8]>,
|
||||||
pub k_wrapper: K,
|
pub k_wrapper: K,
|
||||||
pub v_wrapper: V,
|
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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -76,7 +76,7 @@ impl Env {
|
|||||||
pub fn rw_txn<R>(&self, func: impl FnOnce(&Txn<RW>) -> anyhow::Result<R>) -> anyhow::Result<R> {
|
pub fn rw_txn<R>(&self, func: impl FnOnce(&Txn<RW>) -> anyhow::Result<R>) -> anyhow::Result<R> {
|
||||||
let txn = self.begin_rw_txn()?;
|
let txn = self.begin_rw_txn()?;
|
||||||
let result = func(&txn)?;
|
let result = func(&txn)?;
|
||||||
txn.commit()?;
|
txn.commit().context("Failed to commit")?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 as_byte_slice(&self) -> &[u8];
|
||||||
fn from_byte_slice(bytes: &[u8]) -> anyhow::Result<&Self>;
|
fn from_byte_slice(bytes: &[u8]) -> anyhow::Result<&Self>;
|
||||||
|
fn from_owned_bytes(bytes: Vec<u8>) -> anyhow::Result<Self::Owned>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ZeroCopyByteWrapper for [u8] {
|
impl ZeroCopyByteWrapper for [u8] {
|
||||||
@ -82,6 +83,10 @@ impl ZeroCopyByteWrapper for [u8] {
|
|||||||
fn from_byte_slice(bytes: &[u8]) -> anyhow::Result<&Self> {
|
fn from_byte_slice(bytes: &[u8]) -> anyhow::Result<&Self> {
|
||||||
Ok(bytes)
|
Ok(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn from_owned_bytes(bytes: Vec<u8>) -> anyhow::Result<Self::Owned> {
|
||||||
|
Ok(bytes)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ZeroCopyByteWrapper for str {
|
impl ZeroCopyByteWrapper for str {
|
||||||
@ -92,4 +97,8 @@ impl ZeroCopyByteWrapper for str {
|
|||||||
fn from_byte_slice(bytes: &[u8]) -> anyhow::Result<&Self> {
|
fn from_byte_slice(bytes: &[u8]) -> anyhow::Result<&Self> {
|
||||||
Ok(std::str::from_utf8(bytes)?)
|
Ok(std::str::from_utf8(bytes)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn from_owned_bytes(bytes: Vec<u8>) -> anyhow::Result<Self::Owned> {
|
||||||
|
Ok(String::from_utf8(bytes)?)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user