2021-10-07 16:44:01 +02:00
|
|
|
use std::{
|
|
|
|
ptr::NonNull,
|
|
|
|
ops::Deref,
|
|
|
|
};
|
|
|
|
|
2021-10-20 18:37:50 +02:00
|
|
|
use crate::db::Transaction;
|
2021-10-07 16:44:01 +02:00
|
|
|
|
|
|
|
/// Memory Fixpoint for a value in the DB
|
|
|
|
///
|
|
|
|
/// LMDB binds lifetimes of buffers to the transaction that returned the buffer. As long as this
|
|
|
|
/// transaction is not `commit()`ed, `abort()`ed or `reset()`ed the pages containing these values
|
|
|
|
/// are not returned into circulation.
|
|
|
|
/// This struct encodes this by binding a live reference to the Transaction to the returned
|
|
|
|
/// and interpreted buffer. The placeholder `T` is the container for the transaction. This may be a
|
|
|
|
/// plain `RoTransaction<'env>`, a `Rc<RoTxn>` (meaning Fix is !Send) or an `Arc<RoTxn>`, depending
|
|
|
|
/// on your needs.
|
|
|
|
pub struct LMDBorrow<T, V> {
|
|
|
|
ptr: NonNull<V>,
|
|
|
|
txn: T,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'env, T, V> LMDBorrow<T, V>
|
|
|
|
where T: Transaction,
|
|
|
|
{
|
2021-10-13 04:57:40 +02:00
|
|
|
pub unsafe fn new(ptr: NonNull<V>, txn: T) -> Self {
|
2021-10-20 18:37:50 +02:00
|
|
|
Self { ptr: ptr.into(), txn }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn unwrap_txn(self) -> T {
|
|
|
|
self.txn
|
2021-10-07 16:44:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'env, T, V> Deref for LMDBorrow<T, V>
|
|
|
|
{
|
|
|
|
type Target = V;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
// As long as the transaction is kept alive (which it is, because it's in self) state is a
|
|
|
|
// valid pointer so this is safe.
|
|
|
|
unsafe { self.ptr.as_ref() }
|
|
|
|
}
|
2021-10-20 18:37:50 +02:00
|
|
|
}
|