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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user