|
|
|
|
@ -1,40 +1,41 @@
|
|
|
|
|
use crate::{
|
|
|
|
|
error::{mdbx_result, Error, Result},
|
|
|
|
|
flags::*,
|
|
|
|
|
mdbx_try_optional,
|
|
|
|
|
transaction::{TransactionKind, TransactionPtr, RW},
|
|
|
|
|
TableObject, Transaction,
|
|
|
|
|
};
|
|
|
|
|
use std::{borrow::Cow, fmt, marker::PhantomData, mem, ptr};
|
|
|
|
|
|
|
|
|
|
use libc::c_void;
|
|
|
|
|
|
|
|
|
|
use ffi::{
|
|
|
|
|
MDBX_cursor_op, MDBX_FIRST, MDBX_FIRST_DUP, MDBX_GET_BOTH, MDBX_GET_BOTH_RANGE,
|
|
|
|
|
MDBX_GET_CURRENT, MDBX_GET_MULTIPLE, MDBX_LAST, MDBX_LAST_DUP, MDBX_NEXT, MDBX_NEXT_DUP,
|
|
|
|
|
MDBX_NEXT_MULTIPLE, MDBX_NEXT_NODUP, MDBX_PREV, MDBX_PREV_DUP, MDBX_PREV_MULTIPLE,
|
|
|
|
|
MDBX_PREV_NODUP, MDBX_SET, MDBX_SET_KEY, MDBX_SET_LOWERBOUND, MDBX_SET_RANGE,
|
|
|
|
|
};
|
|
|
|
|
use libc::c_void;
|
|
|
|
|
use std::{borrow::Cow, fmt, marker::PhantomData, mem, ptr};
|
|
|
|
|
|
|
|
|
|
use crate::{
|
|
|
|
|
error::{mdbx_result, Error, Result},
|
|
|
|
|
flags::*,
|
|
|
|
|
mdbx_try_optional,
|
|
|
|
|
transaction::{TransactionKind, RW},
|
|
|
|
|
TableObject, Transaction,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// A cursor for navigating the items within a database.
|
|
|
|
|
pub struct Cursor<'txn, K>
|
|
|
|
|
pub struct Cursor<K>
|
|
|
|
|
where
|
|
|
|
|
K: TransactionKind,
|
|
|
|
|
{
|
|
|
|
|
txn: TransactionPtr,
|
|
|
|
|
txn: Transaction<K>,
|
|
|
|
|
cursor: *mut ffi::MDBX_cursor,
|
|
|
|
|
_marker: PhantomData<fn(&'txn (), K)>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'txn, K> Cursor<'txn, K>
|
|
|
|
|
impl<K> Cursor<K>
|
|
|
|
|
where
|
|
|
|
|
K: TransactionKind,
|
|
|
|
|
{
|
|
|
|
|
pub(crate) fn new(txn: &'txn Transaction<K>, dbi: ffi::MDBX_dbi) -> Result<Self> {
|
|
|
|
|
pub(crate) fn new(txn: Transaction<K>, dbi: ffi::MDBX_dbi) -> Result<Self> {
|
|
|
|
|
let mut cursor: *mut ffi::MDBX_cursor = ptr::null_mut();
|
|
|
|
|
let txn = txn.txn_ptr();
|
|
|
|
|
unsafe {
|
|
|
|
|
mdbx_result(txn.txn_execute(|txn| ffi::mdbx_cursor_open(txn, dbi, &mut cursor)))?;
|
|
|
|
|
}
|
|
|
|
|
Ok(Self { txn, cursor, _marker: PhantomData })
|
|
|
|
|
Ok(Self { txn, cursor })
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn new_at_position(other: &Self) -> Result<Self> {
|
|
|
|
|
@ -43,7 +44,7 @@ where
|
|
|
|
|
|
|
|
|
|
let res = ffi::mdbx_cursor_copy(other.cursor(), cursor);
|
|
|
|
|
|
|
|
|
|
let s = Self { txn: other.txn.clone(), cursor, _marker: PhantomData };
|
|
|
|
|
let s = Self { txn: other.txn.clone(), cursor };
|
|
|
|
|
|
|
|
|
|
mdbx_result(res)?;
|
|
|
|
|
|
|
|
|
|
@ -59,6 +60,24 @@ where
|
|
|
|
|
self.cursor
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns an Iterator over the raw key value slices
|
|
|
|
|
///
|
|
|
|
|
/// Note: The lifetime ensures that the transaction is kept alive while entries are used
|
|
|
|
|
pub fn into_iter_slices<'cur>(self) -> IntoIter<'cur, K, Cow<'cur, [u8]>, Cow<'cur, [u8]>> {
|
|
|
|
|
self.into_iter()
|
|
|
|
|
}
|
|
|
|
|
/// Returns an Iterator over key value pairs of the cursor
|
|
|
|
|
///
|
|
|
|
|
/// Note: The lifetime ensures that the transaction is kept alive while entries are used
|
|
|
|
|
#[allow(clippy::should_implement_trait)]
|
|
|
|
|
pub fn into_iter<'cur, Key, Value>(self) -> IntoIter<'cur, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
IntoIter::new(self, MDBX_NEXT, MDBX_NEXT)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Retrieves a key/data pair from the cursor. Depending on the cursor op,
|
|
|
|
|
/// the current key may be returned.
|
|
|
|
|
fn get<Key, Value>(
|
|
|
|
|
@ -68,8 +87,8 @@ where
|
|
|
|
|
op: MDBX_cursor_op,
|
|
|
|
|
) -> Result<(Option<Key>, Value, bool)>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
unsafe {
|
|
|
|
|
let mut key_val = slice_to_val(key);
|
|
|
|
|
@ -105,7 +124,7 @@ where
|
|
|
|
|
op: MDBX_cursor_op,
|
|
|
|
|
) -> Result<Option<Value>>
|
|
|
|
|
where
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
let (_, v, _) = mdbx_try_optional!(self.get::<(), Value>(key, data, op));
|
|
|
|
|
|
|
|
|
|
@ -119,8 +138,8 @@ where
|
|
|
|
|
op: MDBX_cursor_op,
|
|
|
|
|
) -> Result<Option<(Key, Value)>>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
let (k, v, _) = mdbx_try_optional!(self.get(key, data, op));
|
|
|
|
|
|
|
|
|
|
@ -130,8 +149,8 @@ where
|
|
|
|
|
/// Position at first key/data item.
|
|
|
|
|
pub fn first<Key, Value>(&mut self) -> Result<Option<(Key, Value)>>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_full(None, None, MDBX_FIRST)
|
|
|
|
|
}
|
|
|
|
|
@ -139,7 +158,7 @@ where
|
|
|
|
|
/// [DatabaseFlags::DUP_SORT]-only: Position at first data item of current key.
|
|
|
|
|
pub fn first_dup<Value>(&mut self) -> Result<Option<Value>>
|
|
|
|
|
where
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_value(None, None, MDBX_FIRST_DUP)
|
|
|
|
|
}
|
|
|
|
|
@ -147,7 +166,7 @@ where
|
|
|
|
|
/// [DatabaseFlags::DUP_SORT]-only: Position at key/data pair.
|
|
|
|
|
pub fn get_both<Value>(&mut self, k: &[u8], v: &[u8]) -> Result<Option<Value>>
|
|
|
|
|
where
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_value(Some(k), Some(v), MDBX_GET_BOTH)
|
|
|
|
|
}
|
|
|
|
|
@ -156,7 +175,7 @@ where
|
|
|
|
|
/// equal to specified data.
|
|
|
|
|
pub fn get_both_range<Value>(&mut self, k: &[u8], v: &[u8]) -> Result<Option<Value>>
|
|
|
|
|
where
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_value(Some(k), Some(v), MDBX_GET_BOTH_RANGE)
|
|
|
|
|
}
|
|
|
|
|
@ -164,8 +183,8 @@ where
|
|
|
|
|
/// Return key/data at current cursor position.
|
|
|
|
|
pub fn get_current<Key, Value>(&mut self) -> Result<Option<(Key, Value)>>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_full(None, None, MDBX_GET_CURRENT)
|
|
|
|
|
}
|
|
|
|
|
@ -174,7 +193,7 @@ where
|
|
|
|
|
/// Move cursor to prepare for [Self::next_multiple()].
|
|
|
|
|
pub fn get_multiple<Value>(&mut self) -> Result<Option<Value>>
|
|
|
|
|
where
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_value(None, None, MDBX_GET_MULTIPLE)
|
|
|
|
|
}
|
|
|
|
|
@ -182,8 +201,8 @@ where
|
|
|
|
|
/// Position at last key/data item.
|
|
|
|
|
pub fn last<Key, Value>(&mut self) -> Result<Option<(Key, Value)>>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_full(None, None, MDBX_LAST)
|
|
|
|
|
}
|
|
|
|
|
@ -191,7 +210,7 @@ where
|
|
|
|
|
/// DupSort-only: Position at last data item of current key.
|
|
|
|
|
pub fn last_dup<Value>(&mut self) -> Result<Option<Value>>
|
|
|
|
|
where
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_value(None, None, MDBX_LAST_DUP)
|
|
|
|
|
}
|
|
|
|
|
@ -200,8 +219,8 @@ where
|
|
|
|
|
#[allow(clippy::should_implement_trait)]
|
|
|
|
|
pub fn next<Key, Value>(&mut self) -> Result<Option<(Key, Value)>>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_full(None, None, MDBX_NEXT)
|
|
|
|
|
}
|
|
|
|
|
@ -209,8 +228,8 @@ where
|
|
|
|
|
/// [DatabaseFlags::DUP_SORT]-only: Position at next data item of current key.
|
|
|
|
|
pub fn next_dup<Key, Value>(&mut self) -> Result<Option<(Key, Value)>>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_full(None, None, MDBX_NEXT_DUP)
|
|
|
|
|
}
|
|
|
|
|
@ -219,8 +238,8 @@ where
|
|
|
|
|
/// cursor position. Move cursor to prepare for MDBX_NEXT_MULTIPLE.
|
|
|
|
|
pub fn next_multiple<Key, Value>(&mut self) -> Result<Option<(Key, Value)>>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_full(None, None, MDBX_NEXT_MULTIPLE)
|
|
|
|
|
}
|
|
|
|
|
@ -228,8 +247,8 @@ where
|
|
|
|
|
/// Position at first data item of next key.
|
|
|
|
|
pub fn next_nodup<Key, Value>(&mut self) -> Result<Option<(Key, Value)>>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_full(None, None, MDBX_NEXT_NODUP)
|
|
|
|
|
}
|
|
|
|
|
@ -237,8 +256,8 @@ where
|
|
|
|
|
/// Position at previous data item.
|
|
|
|
|
pub fn prev<Key, Value>(&mut self) -> Result<Option<(Key, Value)>>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_full(None, None, MDBX_PREV)
|
|
|
|
|
}
|
|
|
|
|
@ -246,8 +265,8 @@ where
|
|
|
|
|
/// [DatabaseFlags::DUP_SORT]-only: Position at previous data item of current key.
|
|
|
|
|
pub fn prev_dup<Key, Value>(&mut self) -> Result<Option<(Key, Value)>>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_full(None, None, MDBX_PREV_DUP)
|
|
|
|
|
}
|
|
|
|
|
@ -255,8 +274,8 @@ where
|
|
|
|
|
/// Position at last data item of previous key.
|
|
|
|
|
pub fn prev_nodup<Key, Value>(&mut self) -> Result<Option<(Key, Value)>>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_full(None, None, MDBX_PREV_NODUP)
|
|
|
|
|
}
|
|
|
|
|
@ -264,7 +283,7 @@ where
|
|
|
|
|
/// Position at specified key.
|
|
|
|
|
pub fn set<Value>(&mut self, key: &[u8]) -> Result<Option<Value>>
|
|
|
|
|
where
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_value(Some(key), None, MDBX_SET)
|
|
|
|
|
}
|
|
|
|
|
@ -272,8 +291,8 @@ where
|
|
|
|
|
/// Position at specified key, return both key and data.
|
|
|
|
|
pub fn set_key<Key, Value>(&mut self, key: &[u8]) -> Result<Option<(Key, Value)>>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_full(Some(key), None, MDBX_SET_KEY)
|
|
|
|
|
}
|
|
|
|
|
@ -281,8 +300,8 @@ where
|
|
|
|
|
/// Position at first key greater than or equal to specified key.
|
|
|
|
|
pub fn set_range<Key, Value>(&mut self, key: &[u8]) -> Result<Option<(Key, Value)>>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_full(Some(key), None, MDBX_SET_RANGE)
|
|
|
|
|
}
|
|
|
|
|
@ -291,8 +310,8 @@ where
|
|
|
|
|
/// duplicate data items.
|
|
|
|
|
pub fn prev_multiple<Key, Value>(&mut self) -> Result<Option<(Key, Value)>>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
self.get_full(None, None, MDBX_PREV_MULTIPLE)
|
|
|
|
|
}
|
|
|
|
|
@ -308,8 +327,8 @@ where
|
|
|
|
|
/// exactly and [true] if the next pair was returned.
|
|
|
|
|
pub fn set_lowerbound<Key, Value>(&mut self, key: &[u8]) -> Result<Option<(bool, Key, Value)>>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
let (k, v, found) = mdbx_try_optional!(self.get(Some(key), None, MDBX_SET_LOWERBOUND));
|
|
|
|
|
|
|
|
|
|
@ -323,11 +342,11 @@ where
|
|
|
|
|
/// For databases with duplicate data items ([DatabaseFlags::DUP_SORT]), the
|
|
|
|
|
/// duplicate data items of each key will be returned before moving on to
|
|
|
|
|
/// the next key.
|
|
|
|
|
pub fn iter<Key, Value>(&mut self) -> Iter<'txn, '_, K, Key, Value>
|
|
|
|
|
pub fn iter<Key, Value>(&mut self) -> Iter<'_, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
Self: Sized,
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
Iter::new(self, ffi::MDBX_NEXT, ffi::MDBX_NEXT)
|
|
|
|
|
}
|
|
|
|
|
@ -337,11 +356,11 @@ where
|
|
|
|
|
/// For databases with duplicate data items ([DatabaseFlags::DUP_SORT]), the
|
|
|
|
|
/// duplicate data items of each key will be returned before moving on to
|
|
|
|
|
/// the next key.
|
|
|
|
|
pub fn iter_start<Key, Value>(&mut self) -> Iter<'txn, '_, K, Key, Value>
|
|
|
|
|
pub fn iter_start<Key, Value>(&mut self) -> Iter<'_, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
Self: Sized,
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
Iter::new(self, ffi::MDBX_FIRST, ffi::MDBX_NEXT)
|
|
|
|
|
}
|
|
|
|
|
@ -351,10 +370,10 @@ where
|
|
|
|
|
/// For databases with duplicate data items ([DatabaseFlags::DUP_SORT]), the
|
|
|
|
|
/// duplicate data items of each key will be returned before moving on to
|
|
|
|
|
/// the next key.
|
|
|
|
|
pub fn iter_from<Key, Value>(&mut self, key: &[u8]) -> Iter<'txn, '_, K, Key, Value>
|
|
|
|
|
pub fn iter_from<Key, Value>(&mut self, key: &[u8]) -> Iter<'_, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
let res: Result<Option<((), ())>> = self.set_range(key);
|
|
|
|
|
if let Err(error) = res {
|
|
|
|
|
@ -366,30 +385,30 @@ where
|
|
|
|
|
/// Iterate over duplicate database items. The iterator will begin with the
|
|
|
|
|
/// item next after the cursor, and continue until the end of the database.
|
|
|
|
|
/// Each item will be returned as an iterator of its duplicates.
|
|
|
|
|
pub fn iter_dup<Key, Value>(&mut self) -> IterDup<'txn, '_, K, Key, Value>
|
|
|
|
|
pub fn iter_dup<Key, Value>(&mut self) -> IterDup<'_, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
IterDup::new(self, ffi::MDBX_NEXT)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Iterate over duplicate database items starting from the beginning of the
|
|
|
|
|
/// database. Each item will be returned as an iterator of its duplicates.
|
|
|
|
|
pub fn iter_dup_start<Key, Value>(&mut self) -> IterDup<'txn, '_, K, Key, Value>
|
|
|
|
|
pub fn iter_dup_start<Key, Value>(&mut self) -> IterDup<'_, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
IterDup::new(self, ffi::MDBX_FIRST)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Iterate over duplicate items in the database starting from the given
|
|
|
|
|
/// key. Each item will be returned as an iterator of its duplicates.
|
|
|
|
|
pub fn iter_dup_from<Key, Value>(&mut self, key: &[u8]) -> IterDup<'txn, '_, K, Key, Value>
|
|
|
|
|
pub fn iter_dup_from<Key, Value>(&mut self, key: &[u8]) -> IterDup<'_, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
let res: Result<Option<((), ())>> = self.set_range(key);
|
|
|
|
|
if let Err(error) = res {
|
|
|
|
|
@ -399,10 +418,10 @@ where
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Iterate over the duplicates of the item in the database with the given key.
|
|
|
|
|
pub fn iter_dup_of<Key, Value>(&mut self, key: &[u8]) -> Iter<'txn, '_, K, Key, Value>
|
|
|
|
|
pub fn iter_dup_of<Key, Value>(&mut self, key: &[u8]) -> Iter<'_, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
let res: Result<Option<()>> = self.set(key);
|
|
|
|
|
match res {
|
|
|
|
|
@ -417,7 +436,7 @@ where
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'txn> Cursor<'txn, RW> {
|
|
|
|
|
impl Cursor<RW> {
|
|
|
|
|
/// Puts a key/data pair into the database. The cursor will be positioned at
|
|
|
|
|
/// the new data item, or on failure usually near it.
|
|
|
|
|
pub fn put(&mut self, key: &[u8], data: &[u8], flags: WriteFlags) -> Result<()> {
|
|
|
|
|
@ -449,7 +468,7 @@ impl<'txn> Cursor<'txn, RW> {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'txn, K> Clone for Cursor<'txn, K>
|
|
|
|
|
impl<K> Clone for Cursor<K>
|
|
|
|
|
where
|
|
|
|
|
K: TransactionKind,
|
|
|
|
|
{
|
|
|
|
|
@ -458,7 +477,7 @@ where
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'txn, K> fmt::Debug for Cursor<'txn, K>
|
|
|
|
|
impl<K> fmt::Debug for Cursor<K>
|
|
|
|
|
where
|
|
|
|
|
K: TransactionKind,
|
|
|
|
|
{
|
|
|
|
|
@ -467,7 +486,7 @@ where
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'txn, K> Drop for Cursor<'txn, K>
|
|
|
|
|
impl<K> Drop for Cursor<K>
|
|
|
|
|
where
|
|
|
|
|
K: TransactionKind,
|
|
|
|
|
{
|
|
|
|
|
@ -485,28 +504,16 @@ unsafe fn slice_to_val(slice: Option<&[u8]>) -> ffi::MDBX_val {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsafe impl<'txn, K> Send for Cursor<'txn, K> where K: TransactionKind {}
|
|
|
|
|
unsafe impl<'txn, K> Sync for Cursor<'txn, K> where K: TransactionKind {}
|
|
|
|
|
|
|
|
|
|
impl<'txn, K> IntoIterator for Cursor<'txn, K>
|
|
|
|
|
where
|
|
|
|
|
K: TransactionKind,
|
|
|
|
|
{
|
|
|
|
|
type Item = Result<(Cow<'txn, [u8]>, Cow<'txn, [u8]>)>;
|
|
|
|
|
type IntoIter = IntoIter<'txn, K, Cow<'txn, [u8]>, Cow<'txn, [u8]>>;
|
|
|
|
|
|
|
|
|
|
fn into_iter(self) -> Self::IntoIter {
|
|
|
|
|
IntoIter::new(self, MDBX_NEXT, MDBX_NEXT)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
unsafe impl<K> Send for Cursor<K> where K: TransactionKind {}
|
|
|
|
|
unsafe impl<K> Sync for Cursor<K> where K: TransactionKind {}
|
|
|
|
|
|
|
|
|
|
/// An iterator over the key/value pairs in an MDBX database.
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
pub enum IntoIter<'txn, K, Key, Value>
|
|
|
|
|
pub enum IntoIter<'cur, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
K: TransactionKind,
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
/// An iterator that returns an error on every call to [Iter::next()].
|
|
|
|
|
/// Cursor.iter*() creates an Iter of this type when MDBX returns an error
|
|
|
|
|
@ -521,7 +528,7 @@ where
|
|
|
|
|
/// fails for some reason.
|
|
|
|
|
Ok {
|
|
|
|
|
/// The MDBX cursor with which to iterate.
|
|
|
|
|
cursor: Cursor<'txn, K>,
|
|
|
|
|
cursor: Cursor<K>,
|
|
|
|
|
|
|
|
|
|
/// The first operation to perform when the consumer calls [Iter::next()].
|
|
|
|
|
op: ffi::MDBX_cursor_op,
|
|
|
|
|
@ -529,33 +536,33 @@ where
|
|
|
|
|
/// The next and subsequent operations to perform.
|
|
|
|
|
next_op: ffi::MDBX_cursor_op,
|
|
|
|
|
|
|
|
|
|
_marker: PhantomData<fn(&'txn (), K, Key, Value)>,
|
|
|
|
|
_marker: PhantomData<fn(&'cur (), K, Key, Value)>,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'txn, K, Key, Value> IntoIter<'txn, K, Key, Value>
|
|
|
|
|
impl<'cur, K, Key, Value> IntoIter<'cur, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
K: TransactionKind,
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
/// Creates a new iterator backed by the given cursor.
|
|
|
|
|
fn new(cursor: Cursor<'txn, K>, op: ffi::MDBX_cursor_op, next_op: ffi::MDBX_cursor_op) -> Self {
|
|
|
|
|
IntoIter::Ok { cursor, op, next_op, _marker: PhantomData }
|
|
|
|
|
fn new(cursor: Cursor<K>, op: ffi::MDBX_cursor_op, next_op: ffi::MDBX_cursor_op) -> Self {
|
|
|
|
|
IntoIter::Ok { cursor, op, next_op, _marker: Default::default() }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'txn, K, Key, Value> Iterator for IntoIter<'txn, K, Key, Value>
|
|
|
|
|
impl<'cur, K, Key, Value> Iterator for IntoIter<'cur, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
K: TransactionKind,
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
type Item = Result<(Key, Value)>;
|
|
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
|
match self {
|
|
|
|
|
Self::Ok { cursor, op, next_op, _marker } => {
|
|
|
|
|
Self::Ok { cursor, op, next_op, .. } => {
|
|
|
|
|
let mut key = ffi::MDBX_val { iov_len: 0, iov_base: ptr::null_mut() };
|
|
|
|
|
let mut data = ffi::MDBX_val { iov_len: 0, iov_base: ptr::null_mut() };
|
|
|
|
|
let op = mem::replace(op, *next_op);
|
|
|
|
|
@ -589,11 +596,11 @@ where
|
|
|
|
|
|
|
|
|
|
/// An iterator over the key/value pairs in an MDBX database.
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
pub enum Iter<'txn, 'cur, K, Key, Value>
|
|
|
|
|
pub enum Iter<'cur, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
K: TransactionKind,
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
/// An iterator that returns an error on every call to [Iter::next()].
|
|
|
|
|
/// Cursor.iter*() creates an Iter of this type when MDBX returns an error
|
|
|
|
|
@ -608,7 +615,7 @@ where
|
|
|
|
|
/// fails for some reason.
|
|
|
|
|
Ok {
|
|
|
|
|
/// The MDBX cursor with which to iterate.
|
|
|
|
|
cursor: &'cur mut Cursor<'txn, K>,
|
|
|
|
|
cursor: &'cur mut Cursor<K>,
|
|
|
|
|
|
|
|
|
|
/// The first operation to perform when the consumer calls [Iter::next()].
|
|
|
|
|
op: ffi::MDBX_cursor_op,
|
|
|
|
|
@ -616,31 +623,31 @@ where
|
|
|
|
|
/// The next and subsequent operations to perform.
|
|
|
|
|
next_op: ffi::MDBX_cursor_op,
|
|
|
|
|
|
|
|
|
|
_marker: PhantomData<fn(&'txn (Key, Value))>,
|
|
|
|
|
_marker: PhantomData<fn(&'cur (), K, Key, Value)>,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'txn, 'cur, K, Key, Value> Iter<'txn, 'cur, K, Key, Value>
|
|
|
|
|
impl<'cur, K, Key, Value> Iter<'cur, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
K: TransactionKind,
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
/// Creates a new iterator backed by the given cursor.
|
|
|
|
|
fn new(
|
|
|
|
|
cursor: &'cur mut Cursor<'txn, K>,
|
|
|
|
|
cursor: &'cur mut Cursor<K>,
|
|
|
|
|
op: ffi::MDBX_cursor_op,
|
|
|
|
|
next_op: ffi::MDBX_cursor_op,
|
|
|
|
|
) -> Self {
|
|
|
|
|
Iter::Ok { cursor, op, next_op, _marker: PhantomData }
|
|
|
|
|
Iter::Ok { cursor, op, next_op, _marker: Default::default() }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'txn, 'cur, K, Key, Value> Iterator for Iter<'txn, 'cur, K, Key, Value>
|
|
|
|
|
impl<'cur, K, Key, Value> Iterator for Iter<'cur, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
K: TransactionKind,
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
type Item = Result<(Key, Value)>;
|
|
|
|
|
|
|
|
|
|
@ -682,11 +689,11 @@ where
|
|
|
|
|
///
|
|
|
|
|
/// The yielded items of the iterator are themselves iterators over the duplicate values for a
|
|
|
|
|
/// specific key.
|
|
|
|
|
pub enum IterDup<'txn, 'cur, K, Key, Value>
|
|
|
|
|
pub enum IterDup<'cur, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
K: TransactionKind,
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
/// An iterator that returns an error on every call to Iter.next().
|
|
|
|
|
/// Cursor.iter*() creates an Iter of this type when MDBX returns an error
|
|
|
|
|
@ -701,45 +708,45 @@ where
|
|
|
|
|
/// fails for some reason.
|
|
|
|
|
Ok {
|
|
|
|
|
/// The MDBX cursor with which to iterate.
|
|
|
|
|
cursor: &'cur mut Cursor<'txn, K>,
|
|
|
|
|
cursor: &'cur mut Cursor<K>,
|
|
|
|
|
|
|
|
|
|
/// The first operation to perform when the consumer calls Iter.next().
|
|
|
|
|
op: MDBX_cursor_op,
|
|
|
|
|
|
|
|
|
|
_marker: PhantomData<fn(&'txn (Key, Value))>,
|
|
|
|
|
_marker: PhantomData<fn(&'cur (Key, Value))>,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'txn, 'cur, K, Key, Value> IterDup<'txn, 'cur, K, Key, Value>
|
|
|
|
|
impl<'cur, K, Key, Value> IterDup<'cur, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
K: TransactionKind,
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
/// Creates a new iterator backed by the given cursor.
|
|
|
|
|
fn new(cursor: &'cur mut Cursor<'txn, K>, op: MDBX_cursor_op) -> Self {
|
|
|
|
|
IterDup::Ok { cursor, op, _marker: PhantomData }
|
|
|
|
|
fn new(cursor: &'cur mut Cursor<K>, op: MDBX_cursor_op) -> Self {
|
|
|
|
|
IterDup::Ok { cursor, op, _marker: Default::default() }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'txn, 'cur, K, Key, Value> fmt::Debug for IterDup<'txn, 'cur, K, Key, Value>
|
|
|
|
|
impl<'cur, K, Key, Value> fmt::Debug for IterDup<'cur, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
K: TransactionKind,
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
|
f.debug_struct("IterDup").finish()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'txn, 'cur, K, Key, Value> Iterator for IterDup<'txn, 'cur, K, Key, Value>
|
|
|
|
|
impl<'cur, K, Key, Value> Iterator for IterDup<'cur, K, Key, Value>
|
|
|
|
|
where
|
|
|
|
|
K: TransactionKind,
|
|
|
|
|
Key: TableObject<'txn>,
|
|
|
|
|
Value: TableObject<'txn>,
|
|
|
|
|
Key: TableObject,
|
|
|
|
|
Value: TableObject,
|
|
|
|
|
{
|
|
|
|
|
type Item = IntoIter<'txn, K, Key, Value>;
|
|
|
|
|
type Item = IntoIter<'cur, K, Key, Value>;
|
|
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
|
match self {
|
|
|
|
|
|