Skip to content

Implement Send on Cursors so we can move them between threads #334

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 24 additions & 17 deletions heed/src/cursor.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use std::ops::{Deref, DerefMut};
use std::ptr::NonNull;
use std::{marker, mem, ptr};

use crate::mdb::error::mdb_result;
use crate::mdb::ffi;
use crate::*;

pub struct RoCursor<'txn> {
cursor: *mut ffi::MDB_cursor,
cursor: NonNull<ffi::MDB_cursor>,
_marker: marker::PhantomData<&'txn ()>,
}

Expand All @@ -15,7 +16,7 @@ impl<'txn> RoCursor<'txn> {
let mut cursor: *mut ffi::MDB_cursor = ptr::null_mut();
let mut txn = txn.txn_ptr();
unsafe { mdb_result(ffi::mdb_cursor_open(txn.as_mut(), dbi, &mut cursor))? }
Ok(RoCursor { cursor, _marker: marker::PhantomData })
Ok(RoCursor { cursor: NonNull::new(cursor).unwrap(), _marker: marker::PhantomData })
}

pub fn current(&mut self) -> Result<Option<(&'txn [u8], &'txn [u8])>> {
Expand All @@ -25,7 +26,7 @@ impl<'txn> RoCursor<'txn> {
// Move the cursor on the first database key
let result = unsafe {
mdb_result(ffi::mdb_cursor_get(
self.cursor,
self.cursor.as_mut(),
key_val.as_mut_ptr(),
data_val.as_mut_ptr(),
ffi::cursor_op::MDB_GET_CURRENT,
Expand All @@ -52,7 +53,7 @@ impl<'txn> RoCursor<'txn> {
MoveOperation::Dup => {
unsafe {
mdb_result(ffi::mdb_cursor_get(
self.cursor,
self.cursor.as_mut(),
ptr::null_mut(),
&mut ffi::MDB_val { mv_size: 0, mv_data: ptr::null_mut() },
ffi::cursor_op::MDB_FIRST_DUP,
Expand All @@ -66,7 +67,7 @@ impl<'txn> RoCursor<'txn> {
// Move the cursor on the first database key
let result = unsafe {
mdb_result(ffi::mdb_cursor_get(
self.cursor,
self.cursor.as_mut(),
key_val.as_mut_ptr(),
data_val.as_mut_ptr(),
flag,
Expand All @@ -93,7 +94,7 @@ impl<'txn> RoCursor<'txn> {
MoveOperation::Dup => {
unsafe {
mdb_result(ffi::mdb_cursor_get(
self.cursor,
self.cursor.as_mut(),
ptr::null_mut(),
&mut ffi::MDB_val { mv_size: 0, mv_data: ptr::null_mut() },
ffi::cursor_op::MDB_LAST_DUP,
Expand All @@ -107,7 +108,7 @@ impl<'txn> RoCursor<'txn> {
// Move the cursor on the first database key
let result = unsafe {
mdb_result(ffi::mdb_cursor_get(
self.cursor,
self.cursor.as_mut(),
key_val.as_mut_ptr(),
data_val.as_mut_ptr(),
flag,
Expand All @@ -131,7 +132,7 @@ impl<'txn> RoCursor<'txn> {
// Move the cursor to the specified key
let result = unsafe {
mdb_result(ffi::mdb_cursor_get(
self.cursor,
self.cursor.as_mut(),
&mut key_val,
&mut ffi::MDB_val { mv_size: 0, mv_data: ptr::null_mut() },
ffi::cursor_op::MDB_SET,
Expand All @@ -155,7 +156,7 @@ impl<'txn> RoCursor<'txn> {
// Move the cursor to the specified key
let result = unsafe {
mdb_result(ffi::mdb_cursor_get(
self.cursor,
self.cursor.as_mut(),
&mut key_val,
data_val.as_mut_ptr(),
ffi::cursor_op::MDB_SET_RANGE,
Expand Down Expand Up @@ -186,7 +187,7 @@ impl<'txn> RoCursor<'txn> {
// Move the cursor to the previous non-dup key
let result = unsafe {
mdb_result(ffi::mdb_cursor_get(
self.cursor,
self.cursor.as_mut(),
key_val.as_mut_ptr(),
data_val.as_mut_ptr(),
flag,
Expand Down Expand Up @@ -217,7 +218,7 @@ impl<'txn> RoCursor<'txn> {
// Move the cursor to the next non-dup key
let result = unsafe {
mdb_result(ffi::mdb_cursor_get(
self.cursor,
self.cursor.as_mut(),
key_val.as_mut_ptr(),
data_val.as_mut_ptr(),
flag,
Expand All @@ -238,10 +239,12 @@ impl<'txn> RoCursor<'txn> {

impl Drop for RoCursor<'_> {
fn drop(&mut self) {
unsafe { ffi::mdb_cursor_close(self.cursor) }
unsafe { ffi::mdb_cursor_close(self.cursor.as_mut()) }
}
}

unsafe impl Send for RoCursor<'_> {}

pub struct RwCursor<'txn> {
cursor: RoCursor<'txn>,
}
Expand All @@ -266,7 +269,7 @@ impl<'txn> RwCursor<'txn> {
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
pub unsafe fn del_current(&mut self) -> Result<bool> {
// Delete the current entry
let result = mdb_result(ffi::mdb_cursor_del(self.cursor.cursor, 0));
let result = mdb_result(ffi::mdb_cursor_del(self.cursor.cursor.as_mut(), 0));

match result {
Ok(()) => Ok(true),
Expand Down Expand Up @@ -304,7 +307,7 @@ impl<'txn> RwCursor<'txn> {

// Modify the pointed data
let result = mdb_result(ffi::mdb_cursor_put(
self.cursor.cursor,
self.cursor.cursor.as_mut(),
&mut key_val,
&mut data_val,
ffi::MDB_CURRENT,
Expand Down Expand Up @@ -344,8 +347,12 @@ impl<'txn> RwCursor<'txn> {
let mut reserved = ffi::reserve_size_val(data_size);
let flags = ffi::MDB_RESERVE | flags.bits();

let result =
mdb_result(ffi::mdb_cursor_put(self.cursor.cursor, &mut key_val, &mut reserved, flags));
let result = mdb_result(ffi::mdb_cursor_put(
self.cursor.cursor.as_mut(),
&mut key_val,
&mut reserved,
flags,
));

let found = match result {
Ok(()) => true,
Expand Down Expand Up @@ -392,7 +399,7 @@ impl<'txn> RwCursor<'txn> {

// Modify the pointed data
let result = mdb_result(ffi::mdb_cursor_put(
self.cursor.cursor,
self.cursor.cursor.as_mut(),
&mut key_val,
&mut data_val,
flags.bits(),
Expand Down
Loading